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.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Parameter in select statement

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.

BEGIN
DECLARE @strQuery NVARCHAR(MAX)
DECLARE @CountryId INT
DECLARE @CityId INT

SET @CountryId = 2
SET @CityId = ' AND CityId IN (23,45,85,86)'
SELECT @strQuery= 'SELECT VendorId From Vendors
WHERE CountryId = '+@CountryId+' '+@CityId+'
ORDERBY CreatedDate'

EXEC(@strQuery)
END

I 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 Vendors
WHERE CountryId = @CountryId + ' ' +@CityId
ORDERBY CreatedDate

Please help me to get it working through above select statement.

Thanks

Sharma

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 Publishing
Analytics and OLAP in SQL
Data and Databases: Concepts in Practice
Data, Measurements and Standards in SQL
SQL for Smarties
SQL Programming Style
SQL Puzzles and Answers
Thinking in Sets
Trees and Hierarchies in SQL
Go to Top of Page

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.

BEGIN
DECLARE @strQuery NVARCHAR(MAX)
DECLARE @CountryId INT
DECLARE @CityId INT Varchar(255)

SET @CountryId = 2
SET @CityId = ' AND CityId IN (23,45,85,86)'
SELECT @strQuery= 'SELECT VendorId From Vendors
WHERE CountryId = '+ Cast ( @CountryId as varchar(30)) +' '+@CityId+'
ORDERBY CreatedDate'

EXEC(@strQuery)
END

I 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 Vendors
WHERE CountryId = @CountryId + ' ' +@CityId
ORDERBY CreatedDate

Please help me to get it working through above select statement.

Thanks

Sharma



Go to Top of Page

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 Publishing
Analytics and OLAP in SQL
Data and Databases: Concepts in Practice
Data, Measurements and Standards in SQL
SQL for Smarties
SQL Programming Style
SQL Puzzles and Answers
Thinking in Sets
Trees and Hierarchies in SQL


Go to Top of Page

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
Go to Top of Page

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 INT
SET @i = 0;


WHILE @i < 20000
BEGIN
SET @i = @i + 1
INSERT INTO Tally (Id) VALUES (@i);
END


Now 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 int

SET @NcharacterSeparatedList = '23,45,85,86'
SET @Separator = ','
SET @SeparatorLen = len(@Separator)

SET @NcharacterSeparatedList = @Separator + @NcharacterSeparatedList + @Separator

INSERT INTO @CityIDs
SELECT 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 @CityIDs



Regards,
Jon
Go to Top of Page
   

- Advertisement -