Showing posts with label column. Show all posts
Showing posts with label column. Show all posts

Thursday, March 29, 2012

Create table with 15,000,000 default rows

Hi I want to create a table with one column, which is a identity
column.
Let's say like this:
CREATE TABLE DefaultTable(N int identity(0,1))

Then I want to fill this table with 15,000,000 records, so that I have
a table with the numbers 0 to 14,999,999.

How can I do this as fast as possible. A standard INSERT would take a
long time.

(It can be a temp table or a table variable. I just need a list with
numbered 0 to 15,000,000)

Thank you.

Gidonhttp://www.bizdatasolutions.com/tsql/tblnumbers.asp
--
David Portas
SQL Server MVP
--|||Thanks a lot.

Create table using data from another table

Hi,
How could I create a new table dynamically where columns names are data
from another table?
Example:
I have a table "Table1" with one column "T1Col"
The column contains following data:
"Row1"
"Row2"
"Row3"
Now I would like to "read" data from Table1 and create a new table
Table2 which will contain columns "Row1", "Row2" and
"Row3".
Any help will be appreciated.
Thank you in advance.Google for "transpose" or "cross-tab" or search this newsgroup.
ML
http://milambda.blogspot.com/sql

Tuesday, March 27, 2012

Create Table from Row Data

Hello,
In SQL Server 2000, is it possible to take a table with one field (column), and pivot the table so that the characters in the row data become the field (column) names of another table ( or in a View)? The number of records could vary.

If so, how would I do this?

Sample table;
Create Table dbo.MonthlyData
(
Categories varchar(30) NOT NULL
)

Sample data;

Sales Volume 2005-02
TotRefVol 2005-02
Sales Ratio 2005-02
Sales Volume 2005-03
TotRefVol 2005-03
Sales Ratio 2005-03
Sales Volume 2005-04
TotRefVol 2005-04
Sales Ratio 2005-04

If I am following you correctly; Are you wanting Sales Volume,etc.. to be a column name in a view or table?|||

First; Sorry, the subject should have been 'Create table fields from row data'. To answer your question, each row of sample data is contained within a single column called 'Categories'.

|||

Assuming you had some other value to use with the columns you reference you could do something like:

Create Table dbo.MonthlyData

(

CategoryID int IDENTITY(1,1)

,Categories varchar(30) NOT NULL

,Value varchar(50)

)

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Volume 2005-02', 'Small')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('TotRefVol 2005-02', 'Medium')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Ratio 2005-02', 'Large')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Volume 2005-03', 'Extra Large')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('TotRefVol 2005-03', 'Small')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Ratio 2005-03', 'Medium')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Volume 2005-04', 'Large')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('TotRefVol 2005-04', 'Extra Large')

INSERT dbo.MonthlyData (Categories, [Value]) VALUES('Sales Ratio 2005-04', 'Small')

DECLARE @.string nvarchar(1000)

SELECT @.string = ISNULL(@.string + ', ', '') + QUOTENAME([Value], '''') + QUOTENAME(Categories)

FROM dbo.MonthlyData

SET @.string = 'SELECT ' + @.string

EXEC sp_executesql @.string

This will give you Categories as your column header with associated Value column.

|||

Thank you for your help, I will try this!

cdun2

|||

Thanks again. I had a couple of questions;

-Procedure sp_executesql expects parameter '@.statement' of type 'ntext/nchar/nvarchar'; nvarchar has a 'size' limit of 4000, and ntext cannot be the datatype of local variable @.string. char will handle up to 8000 characters. How can I work around these limitations?

-Could a table be created from the results of sp_executesql @.string so that the column names become fields in the table?

cdun2

|||

Yes, you could alter the syntax

@.sql = 'select ' + @.sql

to

@.sql = 'select ' + @.sql + ' into myTable'

this would keep the columns dynamic. If the number of columns will be static you could create the table and do the following:

@.sql = 'insert myTable (valuelist) select ' + @.sql

|||I realized I didn't answer the first part of your question. If the string you are trying to pass is greater than the 4000 limit of nvarchar you can replace sp_executesql with exec() and make @.string a varchar(8000). It is better practice to use sp_executesql with dynamic sql but in this case it is your only real option.

Sunday, March 25, 2012

Create Table Error

While Creating the Table in SqlServer200 It is givin the Error like

Server: Msg 2749, Level 16, State 2, Line 1
Identity column 'CustID' must be of data type int, bigint, smallint,
tinyint, or decimal or numeric with a scale of 0, and constrained to
be nonnullable.

Can't we create a Identity for character Field?
my Code is follows

CREATE TABLE Rtest (CustID Varchar(10) NOT NULL IDENTITY,
CustName VARCHAR(40) NOT NULL)NO, You cant have an varchar or char field as an identity column

Identity column must be of type numeric ,or the types specified in the error u have given.|||Identity property is to ensure the column value to increase by the defined step. How would a varchar increase?

CREATE TABLE and column order

I create a table by sending a CREATE TABLE command to the database. The
create is successful but when I look at the table in Enterprise Manager
the order of the columns is in alphabetic order and not in the order I
specified when I issued the CREATE TABLE command. Have the columns
really been created in the order in which I see them under Enterprise
Manager ? If so, how do I enforce that the order of the columns is the
same as the order I specify when I created the table ?"Edward Diener" <eddielee_no_spam_here@.tropicsoft.com> wrote in message
news:#Ygoih6XFHA.796@.TK2MSFTNGP09.phx.gbl...
> I create a table by sending a CREATE TABLE command to the database. The
> create is successful but when I look at the table in Enterprise Manager
> the order of the columns is in alphabetic order and not in the order I
> specified when I issued the CREATE TABLE command. Have the columns
> really been created in the order in which I see them under Enterprise
> Manager ? If so, how do I enforce that the order of the columns is the
> same as the order I specify when I created the table ?
Edward,
Does it really matter what order the columns are in? On the data page
itself, the column are put in to an order that SQL Server specifies complete
with headers on each row, null and varchar bitmaps for the row data, and
then the actual row data. If you are using blob objects (text, ntext,
image) then they don't necessarily even live in the row itself, but have
16-byte pointers to other data pages.
To ensure that your data is SELECTed INSERTed and UPDATEed properly, ensure
that you specify a column list in these statements.
Rick Sawtell
MCT, MCSD, MCDBA|||Edward
Are you sure?
I did small test
CREATE TABLE Test8
(
B INT,
A INT
)
Looking in EM I see the same order
Why the order of the columns is so important for you?
When you perform SELECT statement you can specify any order of columns.
"Edward Diener" <eddielee_no_spam_here@.tropicsoft.com> wrote in message
news:%23Ygoih6XFHA.796@.TK2MSFTNGP09.phx.gbl...
> I create a table by sending a CREATE TABLE command to the database. The
> create is successful but when I look at the table in Enterprise Manager
> the order of the columns is in alphabetic order and not in the order I
> specified when I issued the CREATE TABLE command. Have the columns
> really been created in the order in which I see them under Enterprise
> Manager ? If so, how do I enforce that the order of the columns is the
> same as the order I specify when I created the table ?|||You can create a view on the table specifying the order on your own.
HTH, Jens Suessmeyer.
http://www.sqlserver2005.de
--
"Edward Diener" <eddielee_no_spam_here@.tropicsoft.com> schrieb im
Newsbeitrag news:%23Ygoih6XFHA.796@.TK2MSFTNGP09.phx.gbl...
>I create a table by sending a CREATE TABLE command to the database. The
>create is successful but when I look at the table in Enterprise Manager the
>order of the columns is in alphabetic order and not in the order I
>specified when I issued the CREATE TABLE command. Have the columns really
>been created in the order in which I see them under Enterprise Manager ? If
>so, how do I enforce that the order of the columns is the same as the order
>I specify when I created the table ?|||Even though tables in relational databases do not have a "column order"
associated with them, SQL often associates positional significance to the
order of columns in a table. However except in a few circumstances, such
significance of the column order offer little or no benefits.
Not necessarily. To find the order of columns in t-SQL, you can query the
metadata and verify the ORDINAL_POSITION column like:
EXEC sp_columns tbl
Anith|||Rick Sawtell wrote:
> "Edward Diener" <eddielee_no_spam_here@.tropicsoft.com> wrote in message
> news:#Ygoih6XFHA.796@.TK2MSFTNGP09.phx.gbl...
>
>
> Edward,
> Does it really matter what order the columns are in?
Very much so. Are you telling me that I can not ensure the column order
in SQL Server when I create a table ?

> On the data page
> itself, the column are put in to an order that SQL Server specifies comple
te
> with headers on each row, null and varchar bitmaps for the row data, and
> then the actual row data.
When you say "the data page", to what are you referring ?

> If you are using blob objects (text, ntext,
> image) then they don't necessarily even live in the row itself, but have
> 16-byte pointers to other data pages.
> To ensure that your data is SELECTed INSERTed and UPDATEed properly, ensur
e
> that you specify a column list in these statements.
That is not the issue. I need to ensure the actual order of columns is
the same as what I specified when I created the table. Is this the case,
and Enterprise Manager is not showing me the actual column order ? Or is
it the case that SQL Server actually changes the column order from what
I specified when I created the table ? The latter would be terrible.|||Anith Sen wrote:
> Even though tables in relational databases do not have a "column order"
> associated with them, SQL often associates positional significance to the
> order of columns in a table. However except in a few circumstances, such
> significance of the column order offer little or no benefits.
>
>
> Not necessarily. To find the order of columns in t-SQL, you can query the
> metadata and verify the ORDINAL_POSITION column like:
> EXEC sp_columns tbl
>
Sorry, this does work but the order of columns is not what I specified
when I created the table. SQL Server has moved the order of columns.
This is really horrible. There must be some way to ensure that the order
of columns in the table is the same as what I specified when I created
the table.|||Uri Dimant wrote:
> Edward
> Are you sure?
> I did small test
> CREATE TABLE Test8
> (
> B INT,
> A INT
> )
> Looking in EM I see the same order
Try adding primary keys not on the first column.

> Why the order of the columns is so important for you?
I am migrating data from one RDBMS to SQL Server. It is much easier if
the column order is the same in the from and to tables.
> When you perform SELECT statement you can specify any order of columns.
>
>
> "Edward Diener" <eddielee_no_spam_here@.tropicsoft.com> wrote in message
> news:%23Ygoih6XFHA.796@.TK2MSFTNGP09.phx.gbl...
>|||Did you specify the correct table name in place of "tbl"?
Note that the column returned as ORDINAL_POSITION by sp_columns does
NOT necessarily reflect the order in which the columns were defined. If
you insert columns with EM then the table is recreated and you may not
see the result you expect. Also, this behaviour is subject to change in
future versions because EM is going away. Don't rely on it.
David Portas
SQL Server MVP
--|||Edward wrote on Mon, 23 May 2005 11:41:44 -0400:

> Anith Sen wrote:
> Running this stored procedure under SQL Server 7 Query Analyzer I get no
> rows returned.
Check you are putting your own table name in place of tbl, and you are in
the right database. Works fine here on my SQL 7 and SQL 2K servers.
Dan

Create table - default for column (sql 2000)

When I have a table with two columns, can the second column default to
a value based on the value from the first column on an inserted record?
I read the section below in BOL ALTER TABLE but can't make head nor
toes.
E. Alter a table to add several columns with constraints
...
column_c INT NULL
CONSTRAINT column_c_fk
REFERENCES doc_exe(column_a),
...
Can someone explain what REFERENCES is for?
regards,
Gerard> When I have a table with two columns, can the second column default to
> a value based on the value from the first column on an inserted record?
CREATE TABLE dbo.foo
(
column_a VARCHAR(32),
column_b AS CONVERT(CHAR(8), LEFT(column_a, 8))
);
GO
SET NOCOUNT ON;
INSERT dbo.foo(column_a) SELECT 'barblatmortsplunge';
SELECT column_a, column_b FROM dbo.foo;
DROP TABLE dbo.foo;
However, my suggestion is usually to have this kind of thing in a view,
since you can always calculate it at SELECT time, without having to store it
and without tempting users to try and update it, have it be included in
column lists produced by code generators, etc. etc. For example, this
accomplishes the same thing:
CREATE TABLE dbo.foo
(
column_a VARCHAR(32)
);
GO
CREATE VIEW dbo.foo_view
AS
SELECT
column_a,
column_b = LEFT(column_a, 8)
FROM
dbo.foo
GO
SET NOCOUNT ON;
INSERT dbo.foo(column_a) SELECT 'barblatmortsplunge';
SELECT column_a, column_b FROM dbo.foo_view;
DROP VIEW dbo.foo_view;
DROP TABLE dbo.foo;

> Can someone explain what REFERENCES is for?
A foreign key constraint is completely different from what you are asking
about (computed columns). REFERENCES is indicating a separate table (think
master/detail, child/parent, and just about any type of entity
relationship). If you have an Orders table, a Customers table, a Products
table and an OrderDetails table, it is usually set up something like this
(Celko, you know where you can cram your IDENTITY comments):
CREATE TABLE dbo.Products
(
ProductID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
/*...other columns...*/
);
GO
CREATE TABLE dbo.Customers
(
CustomerID BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
/*...other columns...*/
);
GO
CREATE TABLE dbo.Orders
(
OrderID BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
CustomerID BIGINT NOT NULL FOREIGN KEY REFERENCES
dbo.Customers(CustomerID),
/*...other columns...*/
);
GO
CREATE TABLE dbo.OrderDetails
(
OrderID BIGINT FOREIGN KEY REFERENCES dbo.Orders(OrderID),
ProductID INT FOREIGN KEY REFERENCES dbo.Products(ProductID),
Quantity INT,
/*...other columns...*/
PRIMARY KEY(OrderID, ProductID)
);
GO|||"References" token as shown here is a method to explain that the new
column contents must conform to the contents of another table/column
before an INSERT or UPDATE is allowed.
No related to what you are asking to get accomplished. Sounds more like
you might be asking for a trigger which should only be used as a last
ditch effort when making the changes at the (each) of the client
interface is not possible.
Example of simple trigger:
if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[tgr_sample_insert_update]') and OBJECTPROPERTY(id,
N'IsTrigger') = 1)
drop trigger [dbo].[tgr_sample_insert_update]
GO
CREATE TRIGGER dbo.tgr_sample_insert_update ON dbo.tmp_sample
FOR INSERT,UPDATE
AS
SET NOCOUNT ON
UPDATE inserted SET colb = cola * tax_percentage
GO
Cheers
http://rickhathaway.blogspot.com/|||Thanks to you both for your replies. I will experiment a little to see
which is best for me.
regards,
Gerard|||The computed column was not an option as it can not be updated, quite
logical really.
A trigger was too much overhead for what I was trying to achieve so I I
have resolved my issue by including the logic to set the value of the
column on the "client side"
The reason I was wondering about REFERENCES was that I hoped that
something like this would be possible:
create table aTest (
col_a int default 0,
col_b as case when col_a = 1 then 1 when col_a = 2 then 2 else 3 end
)
insert into aTest (col_a) values (0)
select * from aTest
update aTest set col_b = 9
drop table aTest
--
But as I noted above, the update cannot be done.
Thanks again for your replies.
regards,
Gerard

create subtotals dynamically

I am trying to dynamically create subtotals base on values in a column. I also have to group by year. I have gotten the group by year. I used the (previous function) to check for the year and col1 not being equal. I am getting the first subtotal back, don't know how to proceed in my function to return the remaining subtotals

i.e.

col1 col2 col3

aaa 111 2005

bbb 222 2006

aaa 333 2006

ccc 444 2005

ccc 555 2006

bbb 666 2006

bbb 777 2006

ddd 888 2007

2005

aaa subtotal: 1

ccc subtotal: 1

total: 2

2006

aaa subtotal: 1

bbb subtotal: 3

ccc subtotal: 1

total: 5

2007

ddd subtotal: 1

total: 1

grandtotal:

aaa 2

bbb 3

ccc 2

ddd 1

totalnumber 8

I found the solution.

Thanks

Thursday, March 22, 2012

Create Statistics on NonIndexed Column

Hello. Could someone explain to me why it might be desirable to create a
statistic on a non-indexed column?
Thank you."Amos Soma" <amos_j_soma@.yahoo.com> wrote in message
news:%23X4AxZWBGHA.3604@.TK2MSFTNGP09.phx.gbl...
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.
>
The more information the query optimizer has, the better decisions it can
make.
Having statistics on a column that is not part of an index may help it make
better decisions about join strategies, table-scans versus index
seeks/scans, bookmark lookups and so forth.
Rick Sawtell
MCT, MCSD, MCDBA|||Here are some examples to illustrate Rick's statement. Suppose you have
the following table:
CREATE TABLE Persons
(PersonID int not null PRIMARY KEY CLUSTERED
,LastName varchar(100) not null
,FirstName varchar(100) not null
,Address varchar(100) null
-- many other columns, very wide table
,CONSTRAINT UQ_Persons_Name UNIQUE (LastName, FirstName)
)
Now, the DDL above will create a nonclustered index on (LastName,
FirstName). Now suppose you have the following query:
SELECT *
FROM Persons
WHERE FirstName='Amos'
With the default table settings, SQL Server will auto create statistics
of column FirstName.
With these statistics, the optimizer can estimate how many rows there
are with FirstName 'Amos'. If this is a small percentage, then the
strategy would be to scan the nonclustered index and retrieve the
matching rows from the table (bookmark lookups). If it is a large
percentage, the clustered index will be scanned (basically a table
scan).
Without these statistics, SQL Server will optimizer for the worst case
situation, which in this case means scanning the table (clustered index
scan).
Another example. Suppose you also have this table:
-- just an example. Relation might not make sense
CREATE TABLE Hobbies
(HobbyID int not null PRIMARY KEY CLUSTERED
,Hobby varchar(100) not null UNIQUE
,Comments varchar(100) null
,PersonID int not null REFERENCES Persons
)
-- index on the foreign key
CREATE INDEX IX_Hobbies_PersonsID ON Hobbies(PersonID)
with this query:
SELECT Hobby
FROM Hobbies
INNER JOIN Persons
ON Persons.PersonID = Hobbies.PersonID
WHERE Address = 'Main Street'
AND Comments = 'Todo'
In this case statistics of the columns Persons.Address and
Hobbies.Comments can determine the access path for the query. If column
Comments has a high occurrence of 'Todo' and Address a low occurrence of
'Main Street', then the optimizer might choose to access (scan) the
Persons table first, and then lookup matching rows in Hobbies (and
filter out remaining rows). With different statistics the optimizer
might access (scan) the Hobbies table and then lookup the matching rows
in Persons (and filter out the remaining unwanted rows).
HTH,
Gert-Jan
Amos Soma wrote:
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.sql

Create Statistics on NonIndexed Column

Hello. Could someone explain to me why it might be desirable to create a
statistic on a non-indexed column?
Thank you.
"Amos Soma" <amos_j_soma@.yahoo.com> wrote in message
news:%23X4AxZWBGHA.3604@.TK2MSFTNGP09.phx.gbl...
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.
>
The more information the query optimizer has, the better decisions it can
make.
Having statistics on a column that is not part of an index may help it make
better decisions about join strategies, table-scans versus index
seeks/scans, bookmark lookups and so forth.
Rick Sawtell
MCT, MCSD, MCDBA
|||Here are some examples to illustrate Rick's statement. Suppose you have
the following table:
CREATE TABLE Persons
(PersonID int not null PRIMARY KEY CLUSTERED
,LastName varchar(100) not null
,FirstName varchar(100) not null
,Address varchar(100) null
-- many other columns, very wide table
,CONSTRAINT UQ_Persons_Name UNIQUE (LastName, FirstName)
)
Now, the DDL above will create a nonclustered index on (LastName,
FirstName). Now suppose you have the following query:
SELECT *
FROM Persons
WHERE FirstName='Amos'
With the default table settings, SQL Server will auto create statistics
of column FirstName.
With these statistics, the optimizer can estimate how many rows there
are with FirstName 'Amos'. If this is a small percentage, then the
strategy would be to scan the nonclustered index and retrieve the
matching rows from the table (bookmark lookups). If it is a large
percentage, the clustered index will be scanned (basically a table
scan).
Without these statistics, SQL Server will optimizer for the worst case
situation, which in this case means scanning the table (clustered index
scan).
Another example. Suppose you also have this table:
-- just an example. Relation might not make sense
CREATE TABLE Hobbies
(HobbyID int not null PRIMARY KEY CLUSTERED
,Hobby varchar(100) not null UNIQUE
,Comments varchar(100) null
,PersonID int not null REFERENCES Persons
)
-- index on the foreign key
CREATE INDEX IX_Hobbies_PersonsID ON Hobbies(PersonID)
with this query:
SELECT Hobby
FROM Hobbies
INNER JOIN Persons
ON Persons.PersonID = Hobbies.PersonID
WHERE Address = 'Main Street'
AND Comments = 'Todo'
In this case statistics of the columns Persons.Address and
Hobbies.Comments can determine the access path for the query. If column
Comments has a high occurrence of 'Todo' and Address a low occurrence of
'Main Street', then the optimizer might choose to access (scan) the
Persons table first, and then lookup matching rows in Hobbies (and
filter out remaining rows). With different statistics the optimizer
might access (scan) the Hobbies table and then lookup the matching rows
in Persons (and filter out the remaining unwanted rows).
HTH,
Gert-Jan
Amos Soma wrote:
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.

Create Statistics on NonIndexed Column

Hello. Could someone explain to me why it might be desirable to create a
statistic on a non-indexed column?
Thank you."Amos Soma" <amos_j_soma@.yahoo.com> wrote in message
news:%23X4AxZWBGHA.3604@.TK2MSFTNGP09.phx.gbl...
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.
>
The more information the query optimizer has, the better decisions it can
make.
Having statistics on a column that is not part of an index may help it make
better decisions about join strategies, table-scans versus index
seeks/scans, bookmark lookups and so forth.
Rick Sawtell
MCT, MCSD, MCDBA|||Here are some examples to illustrate Rick's statement. Suppose you have
the following table:
CREATE TABLE Persons
(PersonID int not null PRIMARY KEY CLUSTERED
,LastName varchar(100) not null
,FirstName varchar(100) not null
,Address varchar(100) null
-- many other columns, very wide table
,CONSTRAINT UQ_Persons_Name UNIQUE (LastName, FirstName)
)
Now, the DDL above will create a nonclustered index on (LastName,
FirstName). Now suppose you have the following query:
SELECT *
FROM Persons
WHERE FirstName='Amos'
With the default table settings, SQL Server will auto create statistics
of column FirstName.
With these statistics, the optimizer can estimate how many rows there
are with FirstName 'Amos'. If this is a small percentage, then the
strategy would be to scan the nonclustered index and retrieve the
matching rows from the table (bookmark lookups). If it is a large
percentage, the clustered index will be scanned (basically a table
scan).
Without these statistics, SQL Server will optimizer for the worst case
situation, which in this case means scanning the table (clustered index
scan).
Another example. Suppose you also have this table:
-- just an example. Relation might not make sense
CREATE TABLE Hobbies
(HobbyID int not null PRIMARY KEY CLUSTERED
,Hobby varchar(100) not null UNIQUE
,Comments varchar(100) null
,PersonID int not null REFERENCES Persons
)
-- index on the foreign key
CREATE INDEX IX_Hobbies_PersonsID ON Hobbies(PersonID)
with this query:
SELECT Hobby
FROM Hobbies
INNER JOIN Persons
ON Persons.PersonID = Hobbies.PersonID
WHERE Address = 'Main Street'
AND Comments = 'Todo'
In this case statistics of the columns Persons.Address and
Hobbies.Comments can determine the access path for the query. If column
Comments has a high occurrence of 'Todo' and Address a low occurrence of
'Main Street', then the optimizer might choose to access (scan) the
Persons table first, and then lookup matching rows in Hobbies (and
filter out remaining rows). With different statistics the optimizer
might access (scan) the Hobbies table and then lookup the matching rows
in Persons (and filter out the remaining unwanted rows).
HTH,
Gert-Jan
Amos Soma wrote:
> Hello. Could someone explain to me why it might be desirable to create a
> statistic on a non-indexed column?
> Thank you.

Wednesday, March 21, 2012

Create sequential numbers in a column

I have a temp table that's populated with an insert query in as tored
procedure. The temp table has a uniqueID as the primary key.
In that table I have a column SortOrder.
What I want to do is to create a sequential number in SortOrder but
only for records matching a WHERE statement, for example:
(pardon the shorthand...)
Insert *.tblPermanent into tblTemp
If myField = 1 then
SortOrder = 1(2,3,4,5,....etc.)
else
SortOrder = 0
Thanks
lqLauren Quantrell (laurenquantrell@.hotmail.com) writes:
> I have a temp table that's populated with an insert query in as tored
> procedure. The temp table has a uniqueID as the primary key.
> In that table I have a column SortOrder.
> What I want to do is to create a sequential number in SortOrder but
> only for records matching a WHERE statement, for example:
> (pardon the shorthand...)
> Insert *.tblPermanent into tblTemp
> If myField = 1 then
> SortOrder = 1(2,3,4,5,....etc.)
> else
> SortOrder = 0

There are a lot of things that I don't know about, so I have to make
a guess. First, I make the guess that the tblPermanent has a primary-
key column called id. In such case, you can do:

INSERT tblTemp(id, sortorder, ....)
SELECT id, (SELECT COUNT(*)
FROM tblPermanent b
WHERE b.id >= a.id
AND b.myfield = 1
AND a.myfield = 1), ...
FROM tblPermanent

If this does answer your question, please provide the following:

o CREATE TABLE statements for your table.
o INSERT statements with sample data.
o The desired result from the sample data.

--
Erland Sommarskog, SQL Server MVP, sommar@.algonet.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Monday, March 19, 2012

Create Query

I have a table where the first column has several numbers in numerous
formats. I would like to sort by using the first two digits. (15)
This is what I have right now.
select *
FROM GL1400
WHERE GL_ACCT '15';
GO
Obviosuly in the 300k rows there are a few '15' that are in the middle of
the numbers. I was able to cut the amount of arounious results by doing this
search as the column format is 15-XXXX-XXXX-XXXX
select *
FROM GL1400
WHERE GL_ACCT '15-%';
GO
I have been searching for the command that will only search the first two
characters with no such luck.
Any help would be appreciated.
Thanks
Beginnerselect *
FROM GL1400
WHERE left(GL_ACCT,2) = '15'
GO
http://sqlservercode.blogspot.com/|||Am I missing something, I do not see a formula that you wrote.
here is an example of the culumn:
14-15-123
15-11-123
expected result = 1 row
15-11-123
Given the above example you can see where my curent search failed.
SELECT *
FROM GL1400
where GL_ACCT LIKE '02-%';
GO
Using the above fomula I am getting both results.
"Absar Ahmad" wrote:
> Seems that followign command will help you. Check BOL for details of this
> command:
> Left
> If this is not what you are looking for, please send DDL of GL1400 table a
nd
> a few rows of sample data along with example of expected Result from the
> query.
> "bluesrock12000" wrote:
>|||I am using the LEFT function
LEFT(FIELD,2) = '15'
WHERE left(GL_ACCT,2) = '15'|||Any of the following query should work:
SELECT *
FROM GL1400
where left(GL_ACCT,2) = '15'
or
SELECT *
FROM GL1400
where GL_ACCT like '15%'
Note: The second query can benefit from index on GL_ACCT.
"bluesrock12000" wrote:

> Am I missing something, I do not see a formula that you wrote.
> here is an example of the culumn:
> 14-15-123
> 15-11-123
> expected result = 1 row
> 15-11-123
>
> Given the above example you can see where my curent search failed.
> SELECT *
> FROM GL1400
> where GL_ACCT LIKE '02-%';
> GO
> Using the above fomula I am getting both results.|||
> select *
> FROM GL1400
> WHERE GL_ACCT '15-%';
> GO
> I have been searching for the command that will only search the first two
> characters with no such luck.
select *
FROM GL1400
WHERE GL_ACCT LIKE '15%'
(You had no operator, so what it was effectively doing was a bit like:
SELECT GL_ACCT '15' -- I.e. select the values from GL_ACCT, but give the
column an alias of "15"|||Seems that followign command will help you. Check BOL for details of this
command:
Left
If this is not what you are looking for, please send DDL of GL1400 table and
a few rows of sample data along with example of expected Result from the
query.
"bluesrock12000" wrote:

> I have a table where the first column has several numbers in numerous
> formats. I would like to sort by using the first two digits. (15)
> This is what I have right now.
> select *
> FROM GL1400
> WHERE GL_ACCT '15';
> GO
> Obviosuly in the 300k rows there are a few '15' that are in the middle of
> the numbers. I was able to cut the amount of arounious results by doing th
is
> search as the column format is 15-XXXX-XXXX-XXXX
> select *
> FROM GL1400
> WHERE GL_ACCT '15-%';
> GO
> I have been searching for the command that will only search the first two
> characters with no such luck.
> Any help would be appreciated.
> Thanks
> Beginner|||Thank you for all your help,
That was exactly what I was looking for.
"Absar Ahmad" wrote:

> Any of the following query should work:
> SELECT *
> FROM GL1400
> where left(GL_ACCT,2) = '15'
> or
> SELECT *
> FROM GL1400
> where GL_ACCT like '15%'
> Note: The second query can benefit from index on GL_ACCT.
> "bluesrock12000" wrote:
>
>

Sunday, March 11, 2012

Create procedure error on computed column.

I have the following script that was generated using SMO:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[proc_InsertCaseNote]') AND type in (N'P', N'PC'))

DROP PROCEDURE [dbo].[proc_InsertCaseNote]

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

-- =============================================

-- Author: Erin D. Rowley

-- Create date:

-- Description:

-- =============================================

CREATE PROCEDURE [dbo].[proc_InsertCaseNote]

-- Add the parameters for the stored procedure here

@.ReasonCodeSubCategoryID int,

@.OrderGroupID uniqueidentifier,

@.NoteText text,

@.CustomerEmail varchar(75),

@.EmployeeFirstName varchar(255),

@.EmployeeLastName varchar(255)

AS

BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from

-- interfering with SELECT statements.

insert into CaseNotes (ReasonCodeSubCategoryID, OrderGroupID, NoteText, CustomerEmail, EmployeeFirstName, EmployeeLastName, DateCreated)

values (@.ReasonCodeSubCategoryID, @.OrderGroupID, @.NoteText, @.CustomerEmail, @.EmployeeFirstName, @.EmployeeLastName, GetDate())

return @.@.IDENTITY

END

GO

But when I try to run it (in SQL Management Studio) I get the following error:

Msg 271, Level 16, State 1, Procedure proc_InsertCaseNote, Line 18

The column "DateCreated" cannot be modified because it is either a computed column or is the result of a UNION operator.

Any ideas on how to debug this problem?

Thank you.

Kevin

Please post the table DDL.|||

It seems really odd that it DateCreated would be a computed column, but I would also expect that you would know if it was a result of a Union Smile

You can check to see if it is a computed column like this:


create table test
(
notComputed datetime,
computed as getdate()
)
go

select name, is_computed
from sys.columns
where object_id('dbo.test') = object_id
go

Returns:


name is_computed
- --
notComputed 0
computed 1

If you want to see the definition (and other good stuff) use sys.computed_columns:


select name, definition
from sys.computed_columns
where object_id('dbo.test') = object_id
and name = 'computed'


name definition
--
computed (getdate())

|||

Arnie Rowland wrote:

Please post the table DDL.

Sorry but I am not sure how to do this. The script that I am running is creating a stored procedure not a table that is why the error is so strange.

Kevin

|||

Louis Davidson wrote:

It seems really odd that it DateCreated would be a computed column, but I would also expect that you would know if it was a result of a Union

You can check to see if it is a computed column like this:


create table test
(
notComputed datetime,
computed as getdate()
)
go

select name, is_computed
from sys.columns
where object_id('dbo.test') = object_id
go

Returns:


name is_computed
- --
notComputed 0
computed 1

If you want to see the definition (and other good stuff) use sys.computed_columns:


select name, definition
from sys.computed_columns
where object_id('dbo.test') = object_id
and name = 'computed'


name definition
--
computed (getdate())

Thank you. The stored procedure is "automatically" filling in the data for this column through GetDate(). If you were to create a stored procedure and then try to install it on another computer what would your script look like? I am just relying on the script produced by SMO.

Kevin

|||

Right click the table in SSMS, click "Script table to..."

The error is not really all that strange, it is not letting your procedure do something that won't work.

|||

Without seeing the DDL for the table, this is hard to anwser. My guess is that this column was added to the table like this:

Alter table CaseNotes add DateCreated as (getdate())

This would make DateCreated be a computed column which is always set to the current date, not the date the row was inserted. This would not be what you want. If you don't have access to see the table structure for some reason, look at the data in the table and verify that the dates are not all the same. If they are all exactly the same, then you know this is the issue.

What you really want is for DateCreated to have a default of Getdate(), not be a computed column using this statement:

Alter table CaseNotes add DateCreated datetime default getdate()

-Tom

|||

Tom Werz wrote:

Without seeing the DDL for the table, this is hard to anwser. My guess is that this column was added to the table like this:

Alter table CaseNotes add DateCreated as (getdate())

This would make DateCreated be a computed column which is always set to the current date, not the date the row was inserted. This would not be what you want. If you don't have access to see the table structure for some reason, look at the data in the table and verify that the dates are not all the same. If they are all exactly the same, then you know this is the issue.

What you really want is for DateCreated to have a default of Getdate(), not be a computed column using this statement:

Alter table CaseNotes add DateCreated datetime default getdate()

-Tom

The table looks like:

/****** Object: Table [dbo].[CaseNotes] Script Date: 05/07/2007 20:49:37 ******/
CREATE TABLE [dbo].[CaseNotes](
[CaseNotesID] [int] IDENTITY(1,1) NOT NULL,
[ReasonCodeSubCategoryID] [int] NOT NULL,
[OrderGroupId] [uniqueidentifier] NOT NULL,
[NoteText] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[CustomerEmail] [varchar](75) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[EmployeeFirstName] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[EmployeeLastName] [varchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[DateCreated] [datetime] NOT NULL,
CONSTRAINT [PK_CaseNotes] PRIMARY KEY CLUSTERED
(
[CaseNotesID] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[CaseNotes] WITH CHECK ADD CONSTRAINT [FK_CaseNotes_ReasonCodeSubCategory] FOREIGN KEY([ReasonCodeSubCategoryID])
REFERENCES [dbo].[ReasonCodeSubCategory] ([ReasonCodeSubCategoryID])
GO
ALTER TABLE [dbo].[CaseNotes] CHECK CONSTRAINT [FK_CaseNotes_ReasonCodeSubCategory]

The stored procedure is written so that when the row is added the DataCreated is set to the current date when the row is added. I am not sure if I understand what you are suggesting. Does this "create" script help? The stored procedure "works" as is. It seems that I am having a hard time creating a script to create it on another SQL server.

Reproduced here for reference.

USE [BuySeasons]
GO
/****** Object: StoredProcedure [dbo].[proc_InsertCaseNote] Script Date: 05/07/2007 20:54:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Erin D. Rowley
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE [dbo].[proc_InsertCaseNote]
-- Add the parameters for the stored procedure here
@.ReasonCodeSubCategoryID int,
@.OrderGroupID uniqueidentifier,
@.NoteText text,
@.CustomerEmail varchar(75),
@.EmployeeFirstName varchar(255),
@.EmployeeLastName varchar(255)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
insert into CaseNotes (ReasonCodeSubCategoryID, OrderGroupID, NoteText, CustomerEmail, EmployeeFirstName, EmployeeLastName, DateCreated)
values (@.ReasonCodeSubCategoryID, @.OrderGroupID, @.NoteText, @.CustomerEmail, @.EmployeeFirstName, @.EmployeeLastName, GetDate())

return @.@.IDENTITY
END

Thank you for your suggestions.

Kevin

Create output columns based on input in custom component

I'm trying to create a fairly simple custom transform component (because I've read that's the easiest one to create) which will take one column from a flat file source and based on the first row create the output columns.

I'm actually trying to write a component that will solve the now well known problem with parsing CSV files in SSIS. I have a lot of source files and all have many columns so a component that can read in the first line from the CSV file and create the output columns automatically will save me lots of time when migrating the old DTS packages.

I have the basic component set up but I'm stuck when trying to override the OnInputPathAttached method because I don't know how to use the inputID to get the first line from the input (the buffer).

Are there any good examples for creating output columns dynamically based on the input buffer?

Should I just give up on on the transform and create a custom source component instead?

Since there aren't any rows in the buffer until runtime, I don't see how this will work. Packages can't change their metadata (inputs / outputs) at runtime. You could write a source that uses the connection manager at design time to read the first line from the file, and add the output columns, but that would be by directly reading the flat file, not by using a row from the buffer.|||

You could try something like this-

IDTSInput90 input = ComponentMetaData.InputCollection[inputID];

This is a design-time action, in the same way as you would "normally" use the flat file source to load a CSV file, and let the designer UI figure out the columns. This will not allow you to change the file layout at run-time, and magically load any file you happen to find. You area aware of this distinction?

From a design pattern perspective, this is not the place to be selecting and generating columns. It would be more sensible to do this either in a UI or ReinitializeMetadata. Validate could detect the stupid state of no input columns selected, and/or it not matching the input, and call RMD.

A source may be cleaner, or even a package generator. I am not clear on what you are really trying to do, and what problem you need to solve.

|||

Thanks,

I'm trying to solve the problem related to a CSV source missing columns for some rows, it's been brought up a few times here in the past but I haven't seen a generic solution that is suitable for multiple DTS packages that are dependent on multiple CSV files all with 50+ columns.

Here's a forum entry on it:

http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2025483&SiteID=17

And Jamie T's explanation with more links:

http://blogs.conchango.com/jamiethomson/archive/2007/05/15/SSIS_3A00_--Flat-File-Connection-Manager-issues.aspx

I'll see if I can get the custom source component working today.

|||

I was able to get the source component working based off an example from Professional SQL Server 2005 Integration Services

http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764584359.html

(The site has a page for downloading the examples).

The example for creating a source component had a couple errors in it (probably from being based off a pre-release version of SSIS).

Here's some of the key code:

Code Snippet

public override void AcquireConnections(object transaction)

{

if (ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager != null)

{

ConnectionManager cm = Microsoft.SqlServer.Dts.Runtime.DtsConvert.ToConnectionManager(ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager);

if (cm.CreationName != "FLATFILE")

{

throw new Exception("The Connection Manager is not a FILE Connection Manager");

}

else

{

_fileExist = (Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType)cm.Properties["FileUsageType"].GetValue(cm);

if (_fileExist != Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType.FileExists)

{

throw new Exception("The type of FILE connection manager must be an Existing File");

}

else

{

_filename = ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager.AcquireConnection(transaction).ToString();

if (_filename == null || _filename.Length == 0)

{

throw new Exception("Nothing returned when grabbing the filename");

}

}

}

}

}

The original example checked "if (cm.CreationName != "FILE")" which should actually be "if (cm.CreationName != "FLATFILE")"

Code Snippet

private void CreateOutputAndMetaDataColumns(IDTSOutput90 output)

{

if (_filename != null || _filename.Length > 0)

{

TextReader tr = File.OpenText(_filename);

string columns = tr.ReadLine();

tr.Close();

_columnNames = columns.Split(",".ToCharArray());

foreach (string columnName in _columnNames)

{

IDTSOutputColumn90 outName = output.OutputColumnCollection.New();

outName.Name = columnName.Trim();

outName.Description = columnName.Trim();

outName.SetDataTypeProperties(DataType.DT_STR, 50, 0, 0, 1252);

//Create an external metadata column to go alongside with it

CreateExternalMetaDataColumn(output.ExternalMetadataColumnCollection, outName);

}

}

}

Just to get the sample working all columns are strings for the moment, for my needs this is all I needed anyways.

Code Snippet

private bool DoesEachOutputColumnHaveAMetaDataColumnAndDoDatatypesMatch(int outputID)

{

IDTSOutput90 output = ComponentMetaData.OutputCollection.GetObjectByID(outputID);

IDTSExternalMetadataColumn90 mdc;

bool rtnVal = true;

int cCount = 0;

foreach (IDTSOutputColumn90 col in output.OutputColumnCollection)

{

if (col.ExternalMetadataColumnID == 0)

{

rtnVal = false;

}

else

{

//mdc = output.ExternalMetadataColumnCollection[col.ExternalMetadataColumnID];

mdc = output.ExternalMetadataColumnCollection[cCount];

if (mdc.DataType != col.DataType || mdc.Length != col.Length || mdc.Precision != col.Precision

|| mdc.Scale != col.Scale || mdc.CodePage != col.CodePage)

{

rtnVal = false;

}

cCount++;

}

}

return rtnVal;

}

This was the other change I needed to make to the example, the collection index doesn't match the column ID.

I'll try to post the full source code online if I get some time so that hopefully it saves someone else the trouble.

Create output columns based on input in custom component

I'm trying to create a fairly simple custom transform component (because I've read that's the easiest one to create) which will take one column from a flat file source and based on the first row create the output columns.

I'm actually trying to write a component that will solve the now well known problem with parsing CSV files in SSIS. I have a lot of source files and all have many columns so a component that can read in the first line from the CSV file and create the output columns automatically will save me lots of time when migrating the old DTS packages.

I have the basic component set up but I'm stuck when trying to override the OnInputPathAttached method because I don't know how to use the inputID to get the first line from the input (the buffer).

Are there any good examples for creating output columns dynamically based on the input buffer?

Should I just give up on on the transform and create a custom source component instead?

Since there aren't any rows in the buffer until runtime, I don't see how this will work. Packages can't change their metadata (inputs / outputs) at runtime. You could write a source that uses the connection manager at design time to read the first line from the file, and add the output columns, but that would be by directly reading the flat file, not by using a row from the buffer.|||

You could try something like this-

IDTSInput90 input = ComponentMetaData.InputCollection[inputID];

This is a design-time action, in the same way as you would "normally" use the flat file source to load a CSV file, and let the designer UI figure out the columns. This will not allow you to change the file layout at run-time, and magically load any file you happen to find. You area aware of this distinction?

From a design pattern perspective, this is not the place to be selecting and generating columns. It would be more sensible to do this either in a UI or ReinitializeMetadata. Validate could detect the stupid state of no input columns selected, and/or it not matching the input, and call RMD.

A source may be cleaner, or even a package generator. I am not clear on what you are really trying to do, and what problem you need to solve.

|||

Thanks,

I'm trying to solve the problem related to a CSV source missing columns for some rows, it's been brought up a few times here in the past but I haven't seen a generic solution that is suitable for multiple DTS packages that are dependent on multiple CSV files all with 50+ columns.

Here's a forum entry on it:

http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2025483&SiteID=17

And Jamie T's explanation with more links:

http://blogs.conchango.com/jamiethomson/archive/2007/05/15/SSIS_3A00_--Flat-File-Connection-Manager-issues.aspx

I'll see if I can get the custom source component working today.

|||

I was able to get the source component working based off an example from Professional SQL Server 2005 Integration Services

http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764584359.html

(The site has a page for downloading the examples).

The example for creating a source component had a couple errors in it (probably from being based off a pre-release version of SSIS).

Here's some of the key code:

Code Snippet

public override void AcquireConnections(object transaction)

{

if (ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager != null)

{

ConnectionManager cm = Microsoft.SqlServer.Dts.Runtime.DtsConvert.ToConnectionManager(ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager);

if (cm.CreationName != "FLATFILE")

{

throw new Exception("The Connection Manager is not a FILE Connection Manager");

}

else

{

_fileExist = (Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType)cm.Properties["FileUsageType"].GetValue(cm);

if (_fileExist != Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType.FileExists)

{

throw new Exception("The type of FILE connection manager must be an Existing File");

}

else

{

_filename = ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager.AcquireConnection(transaction).ToString();

if (_filename == null || _filename.Length == 0)

{

throw new Exception("Nothing returned when grabbing the filename");

}

}

}

}

}

The original example checked "if (cm.CreationName != "FILE")" which should actually be "if (cm.CreationName != "FLATFILE")"

Code Snippet

private void CreateOutputAndMetaDataColumns(IDTSOutput90 output)

{

if (_filename != null || _filename.Length > 0)

{

TextReader tr = File.OpenText(_filename);

string columns = tr.ReadLine();

tr.Close();

_columnNames = columns.Split(",".ToCharArray());

foreach (string columnName in _columnNames)

{

IDTSOutputColumn90 outName = output.OutputColumnCollection.New();

outName.Name = columnName.Trim();

outName.Description = columnName.Trim();

outName.SetDataTypeProperties(DataType.DT_STR, 50, 0, 0, 1252);

//Create an external metadata column to go alongside with it

CreateExternalMetaDataColumn(output.ExternalMetadataColumnCollection, outName);

}

}

}

Just to get the sample working all columns are strings for the moment, for my needs this is all I needed anyways.

Code Snippet

private bool DoesEachOutputColumnHaveAMetaDataColumnAndDoDatatypesMatch(int outputID)

{

IDTSOutput90 output = ComponentMetaData.OutputCollection.GetObjectByID(outputID);

IDTSExternalMetadataColumn90 mdc;

bool rtnVal = true;

int cCount = 0;

foreach (IDTSOutputColumn90 col in output.OutputColumnCollection)

{

if (col.ExternalMetadataColumnID == 0)

{

rtnVal = false;

}

else

{

//mdc = output.ExternalMetadataColumnCollection[col.ExternalMetadataColumnID];

mdc = output.ExternalMetadataColumnCollection[cCount];

if (mdc.DataType != col.DataType || mdc.Length != col.Length || mdc.Precision != col.Precision

|| mdc.Scale != col.Scale || mdc.CodePage != col.CodePage)

{

rtnVal = false;

}

cCount++;

}

}

return rtnVal;

}

This was the other change I needed to make to the example, the collection index doesn't match the column ID.

I'll try to post the full source code online if I get some time so that hopefully it saves someone else the trouble.

Create output columns based on input in custom component

I'm trying to create a fairly simple custom transform component (because I've read that's the easiest one to create) which will take one column from a flat file source and based on the first row create the output columns.

I'm actually trying to write a component that will solve the now well known problem with parsing CSV files in SSIS. I have a lot of source files and all have many columns so a component that can read in the first line from the CSV file and create the output columns automatically will save me lots of time when migrating the old DTS packages.

I have the basic component set up but I'm stuck when trying to override the OnInputPathAttached method because I don't know how to use the inputID to get the first line from the input (the buffer).

Are there any good examples for creating output columns dynamically based on the input buffer?

Should I just give up on on the transform and create a custom source component instead?

Since there aren't any rows in the buffer until runtime, I don't see how this will work. Packages can't change their metadata (inputs / outputs) at runtime. You could write a source that uses the connection manager at design time to read the first line from the file, and add the output columns, but that would be by directly reading the flat file, not by using a row from the buffer.|||

You could try something like this-

IDTSInput90 input = ComponentMetaData.InputCollection[inputID];

This is a design-time action, in the same way as you would "normally" use the flat file source to load a CSV file, and let the designer UI figure out the columns. This will not allow you to change the file layout at run-time, and magically load any file you happen to find. You area aware of this distinction?

From a design pattern perspective, this is not the place to be selecting and generating columns. It would be more sensible to do this either in a UI or ReinitializeMetadata. Validate could detect the stupid state of no input columns selected, and/or it not matching the input, and call RMD.

A source may be cleaner, or even a package generator. I am not clear on what you are really trying to do, and what problem you need to solve.

|||

Thanks,

I'm trying to solve the problem related to a CSV source missing columns for some rows, it's been brought up a few times here in the past but I haven't seen a generic solution that is suitable for multiple DTS packages that are dependent on multiple CSV files all with 50+ columns.

Here's a forum entry on it:

http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2025483&SiteID=17

And Jamie T's explanation with more links:

http://blogs.conchango.com/jamiethomson/archive/2007/05/15/SSIS_3A00_--Flat-File-Connection-Manager-issues.aspx

I'll see if I can get the custom source component working today.

|||

I was able to get the source component working based off an example from Professional SQL Server 2005 Integration Services

http://www.wrox.com/WileyCDA/WroxTitle/productCd-0764584359.html

(The site has a page for downloading the examples).

The example for creating a source component had a couple errors in it (probably from being based off a pre-release version of SSIS).

Here's some of the key code:

Code Snippet

public override void AcquireConnections(object transaction)

{

if (ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager != null)

{

ConnectionManager cm = Microsoft.SqlServer.Dts.Runtime.DtsConvert.ToConnectionManager(ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager);

if (cm.CreationName != "FLATFILE")

{

throw new Exception("The Connection Manager is not a FILE Connection Manager");

}

else

{

_fileExist = (Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType)cm.Properties["FileUsageType"].GetValue(cm);

if (_fileExist != Microsoft.SqlServer.Dts.Runtime.DTSFileConnectionUsageType.FileExists)

{

throw new Exception("The type of FILE connection manager must be an Existing File");

}

else

{

_filename = ComponentMetaData.RuntimeConnectionCollection["File To Read"].ConnectionManager.AcquireConnection(transaction).ToString();

if (_filename == null || _filename.Length == 0)

{

throw new Exception("Nothing returned when grabbing the filename");

}

}

}

}

}

The original example checked "if (cm.CreationName != "FILE")" which should actually be "if (cm.CreationName != "FLATFILE")"

Code Snippet

private void CreateOutputAndMetaDataColumns(IDTSOutput90 output)

{

if (_filename != null || _filename.Length > 0)

{

TextReader tr = File.OpenText(_filename);

string columns = tr.ReadLine();

tr.Close();

_columnNames = columns.Split(",".ToCharArray());

foreach (string columnName in _columnNames)

{

IDTSOutputColumn90 outName = output.OutputColumnCollection.New();

outName.Name = columnName.Trim();

outName.Description = columnName.Trim();

outName.SetDataTypeProperties(DataType.DT_STR, 50, 0, 0, 1252);

//Create an external metadata column to go alongside with it

CreateExternalMetaDataColumn(output.ExternalMetadataColumnCollection, outName);

}

}

}

Just to get the sample working all columns are strings for the moment, for my needs this is all I needed anyways.

Code Snippet

private bool DoesEachOutputColumnHaveAMetaDataColumnAndDoDatatypesMatch(int outputID)

{

IDTSOutput90 output = ComponentMetaData.OutputCollection.GetObjectByID(outputID);

IDTSExternalMetadataColumn90 mdc;

bool rtnVal = true;

int cCount = 0;

foreach (IDTSOutputColumn90 col in output.OutputColumnCollection)

{

if (col.ExternalMetadataColumnID == 0)

{

rtnVal = false;

}

else

{

//mdc = output.ExternalMetadataColumnCollection[col.ExternalMetadataColumnID];

mdc = output.ExternalMetadataColumnCollection[cCount];

if (mdc.DataType != col.DataType || mdc.Length != col.Length || mdc.Precision != col.Precision

|| mdc.Scale != col.Scale || mdc.CodePage != col.CodePage)

{

rtnVal = false;

}

cCount++;

}

}

return rtnVal;

}

This was the other change I needed to make to the example, the collection index doesn't match the column ID.

I'll try to post the full source code online if I get some time so that hopefully it saves someone else the trouble.

Thursday, March 8, 2012

Create Numeric Sequence ID

Can this be written without tmp tables? (tmp tables simulate real tables)
Needed: an extra column indicating the correct sequence based on the order by
condition of databasename,appname.
create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
varchar(200),active bit null,id int identity(1,1) not null)
insert into #tmp1(appname,databasename,comment,active) Select
'EDIBU','Archived','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'ASNTransfer','ASND','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'atcentral.exe','ATCentral','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'AtCentral.exe','OrderEntry','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1 '
insert into #tmp1(appname,databasename,comment,active) Select
'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
create table #tmp (idx int identity(1,1),appname varchar(50) null,
databasename varchar(50) null,comment varchar(200) null,active bit null,id
int null)
insert into #tmp(appname,databasename,comment,active,id)
select * from #tmp1 order by databasename,appname
select * from #tmp
drop table #tmp1
drop table #tmp
Regards,
Jamie
Sure...
SELECT
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id,
count(*)
FROM #tmp1 t1
JOIN #tmp1 t2 ON
t2.databasename <= t1.databasename
and
(t2.databasename < t1.databasename
or t2.appname <= t1.appname)
GROUP BY
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id
Adam Machanic
SQL Server MVP
Author, "Expert SQL Server 2005 Development"
http://www.apress.com/book/bookDisplay.html?bID=10220
"thejamie" <thejamie@.discussions.microsoft.com> wrote in message
news:32FD08CE-A2A8-4BE3-93D0-0F9D740536DA@.microsoft.com...
> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order
> by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename
> varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1 '
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie
|||Which version of SS are you using?
select
appname, databasename, comment, active,
(
select count(*)
from dbo.t1 as b
where b.appname < a.appname
or (b.appname = a.appname and b.databasename <= a.databasename)
) as rn
from
dbo.t1 as a
order by
rn
-- 2005
select
appname, databasename, comment, active,
row_number() over(order by appname, databasename) as rn
from
dbo.t1
order by
rn
go
AMB
"thejamie" wrote:

> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1 '
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie
|||In 2005 can do this: (looking for a 2000 solution still)
select
b.rownum,a.id, a.databasename, a.appname
from
#tmp1a
inner join
(
SELECT ROW_NUMBER () OVER (ORDER BY databasename,appname) AS rowNum, ID
FROM #tmp1
) as b
on a.[id] = b.[id]
order by b.rownum
Regards,
Jamie
"thejamie" wrote:

> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1 '
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie
|||Alejandro,
Just a minor correction... (looking for databasename,appname order rather
than the other way around)
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
and it looks like the one below works too but with only 172 records in my
actual database, there is no way to be sure at this point.
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
Regards,
Jamie
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> Which version of SS are you using?
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from dbo.t1 as b
> where b.appname < a.appname
> or (b.appname = a.appname and b.databasename <= a.databasename)
> ) as rn
> from
> dbo.t1 as a
> order by
> rn
> -- 2005
> select
> appname, databasename, comment, active,
> row_number() over(order by appname, databasename) as rn
> from
> dbo.t1
> order by
> rn
> go
>
> AMB
> "thejamie" wrote:
|||Hi thejamie,

> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
You got it.

> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
It could be working because of the data you have right now, but that is not
the way to proceed when you need a tie breaker.
Example:
declare @.t table (
databasename varchar(50),
appname varchar(50)
)
insert into @.t values('db1', 'app1')
insert into @.t values('db1', 'app2')
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
-- wrong result
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
go
AMB
"thejamie" wrote:
[vbcol=seagreen]
> Alejandro,
> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
>
> --
> Regards,
> Jamie
>
> "Alejandro Mesa" wrote:
|||Toward a better understanding of traditional ranking queries:
http://beyondsql.blogspot.com/2007/06/dataphor-sql-visualizing-ranking-query.html
|||Thanks Steve.
Regards,
Jamie
"Steve Dassin" wrote:

> Toward a better understanding of traditional ranking queries:
> http://beyondsql.blogspot.com/2007/06/dataphor-sql-visualizing-ranking-query.html
>
>
|||Yep, missed the tie breaker... thanks
Regards,
Jamie
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> Hi thejamie,
>
> You got it.
>
> It could be working because of the data you have right now, but that is not
> the way to proceed when you need a tie breaker.
> Example:
> declare @.t table (
> databasename varchar(50),
> appname varchar(50)
> )
> insert into @.t values('db1', 'app1')
> insert into @.t values('db1', 'app2')
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> -- wrong result
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> go
>
> AMB
>
> "thejamie" wrote:

Create Numeric Sequence ID

Can this be written without tmp tables? (tmp tables simulate real tables)
Needed: an extra column indicating the correct sequence based on the order b
y
condition of databasename,appname.
create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
varchar(200),active bit null,id int identity(1,1) not null)
insert into #tmp1(appname,databasename,comment,activ
e) Select
'EDIBU','Archived','x','1'
insert into #tmp1(appname,databasename,comment,activ
e) Select
'ASNTransfer','ASND','x','1'
insert into #tmp1(appname,databasename,comment,activ
e) Select
'atcentral.exe','ATCentral','x','1'
insert into #tmp1(appname,databasename,comment,activ
e) Select
'AtCentral.exe','OrderEntry','x','1'
insert into #tmp1(appname,databasename,comment,activ
e) Select
'ATOMS.dbo. insTDemand','ATSystemProcessing','x','1'
insert into #tmp1(appname,databasename,comment,activ
e) Select
'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
create table #tmp (idx int identity(1,1),appname varchar(50) null,
databasename varchar(50) null,comment varchar(200) null,active bit null,id
int null)
insert into #tmp(appname,databasename,comment,active
,id)
select * from #tmp1 order by databasename,appname
select * from #tmp
drop table #tmp1
drop table #tmp
Regards,
JamieSure...
SELECT
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id,
count(*)
FROM #tmp1 t1
JOIN #tmp1 t2 ON
t2.databasename <= t1.databasename
and
(t2.databasename < t1.databasename
or t2.appname <= t1.appname)
GROUP BY
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id
Adam Machanic
SQL Server MVP
Author, "Expert SQL Server 2005 Development"
http://www.apress.com/book/bookDisplay.html?bID=10220
"thejamie" <thejamie@.discussions.microsoft.com> wrote in message
news:32FD08CE-A2A8-4BE3-93D0-0F9D740536DA@.microsoft.com...
> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order
> by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename
> varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ATOMS.dbo. insTDemand','ATSystemProcessing','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active
,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie|||Which version of SS are you using?
select
appname, databasename, comment, active,
(
select count(*)
from dbo.t1 as b
where b.appname < a.appname
or (b.appname = a.appname and b.databasename <= a.databasename)
) as rn
from
dbo.t1 as a
order by
rn
-- 2005
select
appname, databasename, comment, active,
row_number() over(order by appname, databasename) as rn
from
dbo.t1
order by
rn
go
AMB
"thejamie" wrote:

> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order
by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename varchar(50),comme
nt
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ATOMS.dbo. insTDemand','ATSystemProcessing','x','1'
> insert into #tmp1(appname,databasename,comment,activ
e) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active
,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie|||Alejandro,
Just a minor correction... (looking for databasename,appname order rather
than the other way around)
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
and it looks like the one below works too but with only 172 records in my
actual database, there is no way to be sure at this point.
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
Regards,
Jamie
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> Which version of SS are you using?
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from dbo.t1 as b
> where b.appname < a.appname
> or (b.appname = a.appname and b.databasename <= a.databasename)
> ) as rn
> from
> dbo.t1 as a
> order by
> rn
> -- 2005
> select
> appname, databasename, comment, active,
> row_number() over(order by appname, databasename) as rn
> from
> dbo.t1
> order by
> rn
> go
>
> AMB
> "thejamie" wrote:
>|||Hi thejamie,

> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
You got it.

> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
It could be working because of the data you have right now, but that is not
the way to proceed when you need a tie breaker.
Example:
declare @.t table (
databasename varchar(50),
appname varchar(50)
)
insert into @.t values('db1', 'app1')
insert into @.t values('db1', 'app2')
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
-- wrong result
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
go
AMB
"thejamie" wrote:
[vbcol=seagreen]
> Alejandro,
> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
>
> --
> Regards,
> Jamie
>
> "Alejandro Mesa" wrote:
>|||Toward a better understanding of traditional ranking queries:
[url]http://beyondsql.blogspot.com/2007/06/dataphor-sql-visualizing-ranking-query.html[
/url]|||Thanks Steve.
--
Regards,
Jamie
"Steve Dassin" wrote:

> Toward a better understanding of traditional ranking queries:
> http://beyondsql.blogspot.com/2007/...ry.htm
l
>
>|||Yep, missed the tie breaker... thanks
--
Regards,
Jamie
"Alejandro Mesa" wrote:
[vbcol=seagreen]
> Hi thejamie,
>
> You got it.
>
> It could be working because of the data you have right now, but that is no
t
> the way to proceed when you need a tie breaker.
> Example:
> declare @.t table (
> databasename varchar(50),
> appname varchar(50)
> )
> insert into @.t values('db1', 'app1')
> insert into @.t values('db1', 'app2')
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> -- wrong result
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> go
>
> AMB
>
> "thejamie" wrote:
>

Create Numeric Sequence ID

Can this be written without tmp tables? (tmp tables simulate real tables)
Needed: an extra column indicating the correct sequence based on the order by
condition of databasename,appname.
create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
varchar(200),active bit null,id int identity(1,1) not null)
insert into #tmp1(appname,databasename,comment,active) Select
'EDIBU','Archived','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'ASNTransfer','ASND','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'atcentral.exe','ATCentral','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'AtCentral.exe','OrderEntry','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
insert into #tmp1(appname,databasename,comment,active) Select
'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
create table #tmp (idx int identity(1,1),appname varchar(50) null,
databasename varchar(50) null,comment varchar(200) null,active bit null,id
int null)
insert into #tmp(appname,databasename,comment,active,id)
select * from #tmp1 order by databasename,appname
select * from #tmp
drop table #tmp1
drop table #tmp
--
Regards,
JamieSure...
SELECT
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id,
count(*)
FROM #tmp1 t1
JOIN #tmp1 t2 ON
t2.databasename <= t1.databasename
and
(t2.databasename < t1.databasename
or t2.appname <= t1.appname)
GROUP BY
t1.appname,
t1.databasename,
t1.comment,
t1.active,
t1.id
--
Adam Machanic
SQL Server MVP
Author, "Expert SQL Server 2005 Development"
http://www.apress.com/book/bookDisplay.html?bID=10220
"thejamie" <thejamie@.discussions.microsoft.com> wrote in message
news:32FD08CE-A2A8-4BE3-93D0-0F9D740536DA@.microsoft.com...
> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order
> by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename
> varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie|||Which version of SS are you using?
select
appname, databasename, comment, active,
(
select count(*)
from dbo.t1 as b
where b.appname < a.appname
or (b.appname = a.appname and b.databasename <= a.databasename)
) as rn
from
dbo.t1 as a
order by
rn
-- 2005
select
appname, databasename, comment, active,
row_number() over(order by appname, databasename) as rn
from
dbo.t1
order by
rn
go
AMB
"thejamie" wrote:
> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie|||In 2005 can do this: (looking for a 2000 solution still)
select
b.rownum,a.id, a.databasename, a.appname
from
#tmp1a
inner join
(
SELECT ROW_NUMBER () OVER (ORDER BY databasename,appname) AS rowNum, ID
FROM #tmp1
) as b
on a.[id] = b.[id]
order by b.rownum
--
Regards,
Jamie
"thejamie" wrote:
> Can this be written without tmp tables? (tmp tables simulate real tables)
> Needed: an extra column indicating the correct sequence based on the order by
> condition of databasename,appname.
> create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> varchar(200),active bit null,id int identity(1,1) not null)
> insert into #tmp1(appname,databasename,comment,active) Select
> 'EDIBU','Archived','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ASNTransfer','ASND','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'atcentral.exe','ATCentral','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'AtCentral.exe','OrderEntry','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> insert into #tmp1(appname,databasename,comment,active) Select
> 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> create table #tmp (idx int identity(1,1),appname varchar(50) null,
> databasename varchar(50) null,comment varchar(200) null,active bit null,id
> int null)
> insert into #tmp(appname,databasename,comment,active,id)
> select * from #tmp1 order by databasename,appname
> select * from #tmp
> drop table #tmp1
> drop table #tmp
> --
> Regards,
> Jamie|||Alejandro,
Just a minor correction... (looking for databasename,appname order rather
than the other way around)
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
and it looks like the one below works too but with only 172 records in my
actual database, there is no way to be sure at this point.
select
appname, databasename, comment, active,
(
select count(*)
from migrationdata as b
where b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
migrationdata as a
order by
rn
Regards,
Jamie
"Alejandro Mesa" wrote:
> Which version of SS are you using?
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from dbo.t1 as b
> where b.appname < a.appname
> or (b.appname = a.appname and b.databasename <= a.databasename)
> ) as rn
> from
> dbo.t1 as a
> order by
> rn
> -- 2005
> select
> appname, databasename, comment, active,
> row_number() over(order by appname, databasename) as rn
> from
> dbo.t1
> order by
> rn
> go
>
> AMB
> "thejamie" wrote:
> > Can this be written without tmp tables? (tmp tables simulate real tables)
> > Needed: an extra column indicating the correct sequence based on the order by
> > condition of databasename,appname.
> >
> > create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> > varchar(200),active bit null,id int identity(1,1) not null)
> >
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'EDIBU','Archived','x','1'
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'ASNTransfer','ASND','x','1'
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'atcentral.exe','ATCentral','x','1'
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'AtCentral.exe','OrderEntry','x','1'
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> > insert into #tmp1(appname,databasename,comment,active) Select
> > 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> >
> > create table #tmp (idx int identity(1,1),appname varchar(50) null,
> > databasename varchar(50) null,comment varchar(200) null,active bit null,id
> > int null)
> > insert into #tmp(appname,databasename,comment,active,id)
> > select * from #tmp1 order by databasename,appname
> > select * from #tmp
> >
> > drop table #tmp1
> > drop table #tmp
> >
> > --
> > Regards,
> > Jamie|||Hi thejamie,
> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
You got it.
> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
It could be working because of the data you have right now, but that is not
the way to proceed when you need a tie breaker.
Example:
declare @.t table (
databasename varchar(50),
appname varchar(50)
)
insert into @.t values('db1', 'app1')
insert into @.t values('db1', 'app2')
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename = a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
-- wrong result
select
appname, databasename,
(
select
count(*)
from
@.t as b
where
b.databasename < a.databasename
or ( b.databasename < a.databasename and b.appname <= a.appname)
) as rn
from
@.t as a
order by
rn
go
AMB
"thejamie" wrote:
> Alejandro,
> Just a minor correction... (looking for databasename,appname order rather
> than the other way around)
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
> and it looks like the one below works too but with only 172 records in my
> actual database, there is no way to be sure at this point.
> select
> appname, databasename, comment, active,
> (
> select count(*)
> from migrationdata as b
> where b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> migrationdata as a
> order by
> rn
>
> --
> Regards,
> Jamie
>
> "Alejandro Mesa" wrote:
> > Which version of SS are you using?
> >
> > select
> > appname, databasename, comment, active,
> > (
> > select count(*)
> > from dbo.t1 as b
> > where b.appname < a.appname
> > or (b.appname = a.appname and b.databasename <= a.databasename)
> > ) as rn
> > from
> > dbo.t1 as a
> > order by
> > rn
> >
> > -- 2005
> > select
> > appname, databasename, comment, active,
> > row_number() over(order by appname, databasename) as rn
> > from
> > dbo.t1
> > order by
> > rn
> > go
> >
> >
> > AMB
> >
> > "thejamie" wrote:
> >
> > > Can this be written without tmp tables? (tmp tables simulate real tables)
> > > Needed: an extra column indicating the correct sequence based on the order by
> > > condition of databasename,appname.
> > >
> > > create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> > > varchar(200),active bit null,id int identity(1,1) not null)
> > >
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'EDIBU','Archived','x','1'
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'ASNTransfer','ASND','x','1'
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'atcentral.exe','ATCentral','x','1'
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'AtCentral.exe','OrderEntry','x','1'
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> > > insert into #tmp1(appname,databasename,comment,active) Select
> > > 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> > >
> > > create table #tmp (idx int identity(1,1),appname varchar(50) null,
> > > databasename varchar(50) null,comment varchar(200) null,active bit null,id
> > > int null)
> > > insert into #tmp(appname,databasename,comment,active,id)
> > > select * from #tmp1 order by databasename,appname
> > > select * from #tmp
> > >
> > > drop table #tmp1
> > > drop table #tmp
> > >
> > > --
> > > Regards,
> > > Jamie|||Toward a better understanding of traditional ranking queries:
http://beyondsql.blogspot.com/2007/06/dataphor-sql-visualizing-ranking-query.html|||Thanks Steve.
--
Regards,
Jamie
"Steve Dassin" wrote:
> Toward a better understanding of traditional ranking queries:
> http://beyondsql.blogspot.com/2007/06/dataphor-sql-visualizing-ranking-query.html
>
>|||Yep, missed the tie breaker... thanks
--
Regards,
Jamie
"Alejandro Mesa" wrote:
> Hi thejamie,
> > Just a minor correction... (looking for databasename,appname order rather
> > than the other way around)
> You got it.
> > and it looks like the one below works too but with only 172 records in my
> > actual database, there is no way to be sure at this point.
> >
> > select
> > appname, databasename, comment, active,
> > (
> > select count(*)
> > from migrationdata as b
> > where b.databasename < a.databasename
> > or ( b.databasename < a.databasename and b.appname <= a.appname)
> > ) as rn
> > from
> > migrationdata as a
> > order by
> > rn
> It could be working because of the data you have right now, but that is not
> the way to proceed when you need a tie breaker.
> Example:
> declare @.t table (
> databasename varchar(50),
> appname varchar(50)
> )
> insert into @.t values('db1', 'app1')
> insert into @.t values('db1', 'app2')
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename = a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> -- wrong result
> select
> appname, databasename,
> (
> select
> count(*)
> from
> @.t as b
> where
> b.databasename < a.databasename
> or ( b.databasename < a.databasename and b.appname <= a.appname)
> ) as rn
> from
> @.t as a
> order by
> rn
> go
>
> AMB
>
> "thejamie" wrote:
> > Alejandro,
> > Just a minor correction... (looking for databasename,appname order rather
> > than the other way around)
> >
> > select
> > appname, databasename, comment, active,
> > (
> > select count(*)
> > from migrationdata as b
> > where b.databasename < a.databasename
> > or ( b.databasename = a.databasename and b.appname <= a.appname)
> > ) as rn
> > from
> > migrationdata as a
> > order by
> > rn
> >
> > and it looks like the one below works too but with only 172 records in my
> > actual database, there is no way to be sure at this point.
> >
> > select
> > appname, databasename, comment, active,
> > (
> > select count(*)
> > from migrationdata as b
> > where b.databasename < a.databasename
> > or ( b.databasename < a.databasename and b.appname <= a.appname)
> > ) as rn
> > from
> > migrationdata as a
> > order by
> > rn
> >
> >
> > --
> > Regards,
> > Jamie
> >
> >
> > "Alejandro Mesa" wrote:
> >
> > > Which version of SS are you using?
> > >
> > > select
> > > appname, databasename, comment, active,
> > > (
> > > select count(*)
> > > from dbo.t1 as b
> > > where b.appname < a.appname
> > > or (b.appname = a.appname and b.databasename <= a.databasename)
> > > ) as rn
> > > from
> > > dbo.t1 as a
> > > order by
> > > rn
> > >
> > > -- 2005
> > > select
> > > appname, databasename, comment, active,
> > > row_number() over(order by appname, databasename) as rn
> > > from
> > > dbo.t1
> > > order by
> > > rn
> > > go
> > >
> > >
> > > AMB
> > >
> > > "thejamie" wrote:
> > >
> > > > Can this be written without tmp tables? (tmp tables simulate real tables)
> > > > Needed: an extra column indicating the correct sequence based on the order by
> > > > condition of databasename,appname.
> > > >
> > > > create table #tmp1(appname varchar(50) null,databasename varchar(50),comment
> > > > varchar(200),active bit null,id int identity(1,1) not null)
> > > >
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'EDIBU','Archived','x','1'
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'ASNTransfer','ASND','x','1'
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'atcentral.exe','ATCentral','x','1'
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'AtCentral.exe','OrderEntry','x','1'
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'ATOMS.dbo.insTDemand','ATSystemProcessing','x','1'
> > > > insert into #tmp1(appname,databasename,comment,active) Select
> > > > 'ATOMS.dbo.spConvertFSCOs','EDID','x','1'
> > > >
> > > > create table #tmp (idx int identity(1,1),appname varchar(50) null,
> > > > databasename varchar(50) null,comment varchar(200) null,active bit null,id
> > > > int null)
> > > > insert into #tmp(appname,databasename,comment,active,id)
> > > > select * from #tmp1 order by databasename,appname
> > > > select * from #tmp
> > > >
> > > > drop table #tmp1
> > > > drop table #tmp
> > > >
> > > > --
> > > > Regards,
> > > > Jamie