Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
plugsharma
Starting Member
2 Posts |
Posted - 2010-10-04 : 17:03:27
|
Hi,I need to pass a parameter into a stored procedure which values are dynamic always. Executing a variable which having the Select statement.Following query working fine.BEGINDECLARE @strQuery NVARCHAR(MAX)DECLARE @CountryId INTDECLARE @CityId INTSET @CountryId = 2SET @CityId = ' AND CityId IN (23,45,85,86)'SELECT @strQuery= 'SELECT VendorId From VendorsWHERE CountryId = '+@CountryId+' '+@CityId+'ORDERBY CreatedDate'EXEC(@strQuery)ENDI need to execute above in an open select statement instead of executing @strQuery.Getting error as When trying through following script as "Conversion failed when converting the varchar value ' AND CityId (23,45,85,86)' to data type int" SELECT VendorId From VendorsWHERE CountryId = @CountryId + ' ' +@CityId ORDERBY CreatedDatePlease help me to get it working through above select statement.ThanksSharma  |
|
|
jcelko
Esteemed SQL Purist
547 Posts |
Posted - 2010-10-05 : 11:31:31
|
| Why are you using dynamic SQL at all? Why don't you know about the ISO couuntry codes? Surely you did not cram both a country and city into one column -- they are totally different things. This is all you need to do it right:CREATE PROCEDURE LocateVendorsByLocation(@in_country_code CHAR(3), --iso-3166 @in_city_name VARCHAR(15))AS SELECT vendor_id FROM Vendors WHERE country_code = @in_country_code AND city_name = @in_city_name ORDER BY creation_date;--CELKO--Books in Celko Series for Morgan-Kaufmann PublishingAnalytics and OLAP in SQLData and Databases: Concepts in Practice Data, Measurements and Standards in SQLSQL for SmartiesSQL Programming Style SQL Puzzles and Answers Thinking in SetsTrees and Hierarchies in SQL |
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-10-05 : 11:52:13
|
quote: Originally posted by plugsharma Hi,I need to pass a parameter into a stored procedure which values are dynamic always. Executing a variable which having the Select statement.Following query working fine.BEGINDECLARE @strQuery NVARCHAR(MAX)DECLARE @CountryId INTDECLARE @CityId INT Varchar(255)SET @CountryId = 2SET @CityId = ' AND CityId IN (23,45,85,86)'SELECT @strQuery= 'SELECT VendorId From VendorsWHERE CountryId = '+ Cast ( @CountryId as varchar(30)) +' '+@CityId+'ORDERBY CreatedDate'EXEC(@strQuery)ENDI need to execute above in an open select statement instead of executing @strQuery.Getting error as When trying through following script as "Conversion failed when converting the varchar value ' AND CityId (23,45,85,86)' to data type int" SELECT VendorId From VendorsWHERE CountryId = @CountryId + ' ' +@CityId ORDERBY CreatedDatePlease help me to get it working through above select statement.ThanksSharma 
|
 |
|
|
pk_bohra
Master Smack Fu Yak Hacker
1182 Posts |
Posted - 2010-10-05 : 11:55:08
|
quote: Originally posted by jcelko Why are you using dynamic SQL at all? Why don't you know about the ISO couuntry codes? Surely you did not cram both a country and city into one column -- they are totally different things. This is all you need to do it right:CREATE PROCEDURE LocateVendorsByLocation(@in_country_code CHAR(3), --iso-3166 @in_city_name VARCHAR(15))AS SELECT vendor_id FROM Vendors WHERE country_code = @in_country_code AND city_name = @in_city_name --I think that this will work only for 1 value and not multiple csv values ORDER BY creation_date;--CELKO--Books in Celko Series for Morgan-Kaufmann PublishingAnalytics and OLAP in SQLData and Databases: Concepts in Practice Data, Measurements and Standards in SQLSQL for SmartiesSQL Programming Style SQL Puzzles and Answers Thinking in SetsTrees and Hierarchies in SQL
|
 |
|
|
JonRussell
Starting Member
4 Posts |
Posted - 2010-10-05 : 12:21:49
|
| Sharma,I agree with Celko that you should avoid using dynamic SQL. Let me make a comment about your @CityId variable. It is an integer data type and you are trying to set it to a variable length character data. This will cause a conversion error, which is exactly what the error message says. Others may have a better technique, but the only way I know to pass a variable into a stored procedure that will always be dynamic is to convert your delimited list to a table, then use the table in your query. The challenge to this technique is to parse through the delimited list without using a cursor or WHILE loop. If your list is big enough, it may cause performance problems. I may have an old script I have used to use for this very problem. If I can find it I will post it back.Regards,Jon |
 |
|
|
JonRussell
Starting Member
4 Posts |
Posted - 2010-10-05 : 13:06:29
|
| Sharma,Here is how I convert a delimited list, or CSV, to a table. There may be a better way to this and I would appreciated anyone’s feedback on this. The script avoids using cursors and WHILE loops. Instead, it uses Tally table. The Tally table is just a numbers table that can be used for various purposes, in this case converting a delimited list to a table. You can do this by matching the character index of the delimiter to a number on the Tally table.The first thing you need is the Tally table. Create this table and keep it in your database for future use. Then load the table with some numbers. 20000 should cover most of your needs.CREATE TABLE [Tally] ( [Id] INT NOT NULL);ALTER TABLE [Tally] ADD CONSTRAINT [PK_Tally] PRIMARY KEY CLUSTERED ([Id] ASC) ON [PRIMARY];DECLARE @i INTSET @i = 0;WHILE @i < 20000BEGIN SET @i = @i + 1 INSERT INTO Tally (Id) VALUES (@i);ENDNow that you have your Tally table you can use it to convert a delimited list to table. The query below can be used directly in your stored procedure, or you can create a function so you can reuse it. You will want to use this query to load a temp table or table variable.Set the @NcharacterSeparatedList variable to you delimited list of values. Set the @Separator variable to your delimiter, a comma in this case. Finally, run this query, you should see the four delimited values returned as a table.DECLARE @CityIDs table ( CityID int);DECLARE @NcharacterSeparatedList nvarchar(max), @Separator nvarchar(5)DECLARE @SeparatorLen intSET @NcharacterSeparatedList = '23,45,85,86'SET @Separator = ','SET @SeparatorLen = len(@Separator)SET @NcharacterSeparatedList = @Separator + @NcharacterSeparatedList + @SeparatorINSERT INTO @CityIDsSELECT left( substring( @NcharacterSeparatedList, -- expression Id + @SeparatorLen, -- start charindex( -- length @Separator, -- expr1 @NcharacterSeparatedList, -- expr2 Id + @SeparatorLen -- start location ) - Id - @SeparatorLen ) , 50)FROM Tally WHERE (Id < (len(@NcharacterSeparatedList) - @SeparatorLen) ) AND (substring(@NcharacterSeparatedList, Id, @SeparatorLen) = @Separator)SELECT * FROM @CityIDsRegards,Jon |
 |
|
|
|
|
|
|
|