PDA

View Full Version : ارسال رشته برای شرط in



Sal_64
جمعه 12 مهر 1392, 23:33 عصر
سلام
چرا این قطعه کد جوابی را برنمی گردونه


declare @code varchar(max)
set @code='10,20,30,80,0.6'
select * from table where code in (@code)

تشکر

mehdi.mousavi
شنبه 13 مهر 1392, 07:51 صبح
سلام چرا این قطعه کد جوابی را برنمی گردونه تشکر

سلام.
فیلد code در جدول table، تایپش چیه؟ ممکنه براتون تعریف جدول table رو بهمراه چند نمونه از داده های موجود در اون رو نیز اینجا قرار بدید تا بتونم در پست بعدی دقیق پاسخ بدم؟

موفق باشید.

Sal_64
شنبه 13 مهر 1392, 08:40 صبح
سلام
از نوع varchar
داده ها : 0.1 - 0.3 - 20 - 12365.8 - 13 - 12 و ...

mehdi.mousavi
شنبه 13 مهر 1392, 09:07 صبح
سلام از نوع varchar داده ها : 0.1 - 0.3 - 20 - 12365.8 - 13 - 12 و ...

سلام.
بسیار خوب، چون ورودی شما NVARCHAR هستش، نمیتونید به این شکل از IN استفاده کنید. ابتدا باید به روشی، لیست Comma Separated ای که دارید رو به جدول موقتی تبدیل کنید که هر Element در یک Row قرار بگیره. برای مثال میتونید به این شکل (http://www.sqlservercentral.com/Forums/Topic830317-338-1.aspx) عمل کنید. حالا، میتونید از IN برای بدست آوردن رکورد مورد نظر استفاده کنید. برای سادگی، من کل کد رو براتون می نویسم:

DECLARE @Code NVARCHAR(MAX) = '12, 13, .5';
;WITH parser(lft, rght) AS (
SELECT
LEFT(@Code, CHARINDEX(', ', @Code) - 1),
SUBSTRING(@Code, CHARINDEX(', ', @Code) + 2, DATALENGTH(@Code))
UNION ALL
SELECT
IIF(CHARINDEX(', ', p.rght) = 0, p.rght, LEFT(p.rght, CHARINDEX(', ', p.rght) - 1)),
IIF(CHARINDEX(', ', p.rght) > 0, SUBSTRING(p.rght, CHARINDEX(', ', p.rght) + 2, DATALENGTH(p.rght)), '')
FROM parser p
WHERE DATALENGTH(p.rght) > 0
)
SELECT * FROM @Temp WHERE Code IN (
SELECT lft FROM parser
)

که در اون، جای @Temp باید نام Table مورد نظرتون که داده ها در اون ذخیره شده رو قرار بدید...

موفق باشید.

Sal_64
شنبه 13 مهر 1392, 10:59 صبح
سلام
تشکر
خواستم کد شما داخل کوئری اجرا کنم که به مشکل برخوردم

DECLARE @Code NVARCHAR(MAX)
set @Code= '12, 13, .5'
;WITH parser(lft, rght) AS (
SELECT
LEFT(@Code, CHARINDEX(', ', @Code) - 1),
SUBSTRING(@Code, CHARINDEX(', ', @Code) + 2, DATALENGTH(@Code))
UNION ALL
SELECT
IIF(CHARINDEX(', ', p.rght) = 0, p.rght, LEFT(p.rght, CHARINDEX(', ', p.rght) - 1)),
IIF(CHARINDEX(', ', p.rght) > 0, SUBSTRING(p.rght, CHARINDEX(', ', p.rght) + 2, DATALENGTH(p.rght)), '')
FROM parser p
WHERE DATALENGTH(p.rght) > 0
)
SELECT * FROM jari WHERE Code IN (
SELECT lft FROM parser
)

Msg 102, Level 15, State 1, Line 9
Incorrect syntax near '='.

اما مطلب بعد

چون ورودی شما NVARCHAR هستش، نمیتونید به این شکل از IN استفاده کنید. همونطور که گفتم نوع فیلد varchar
محتویات فیلد اعداد و علامت اعشار هستن
اگر فیلد از نوع اعشار تعریف کنم ، دیگه نیازی به کدهای بالا نیست ؟

تشکر

mehdi.mousavi
شنبه 13 مهر 1392, 11:34 صبح
سلام.
بسیار خوب، احتمالا شما از SQL Server 2012 استفاده نمی کنید، برای همین جای IIF باید از CASE استفاده کنید:

DECLARE @Code NVARCHAR(MAX) = '12, 13, .5';
;WITH parser(lft, rght) AS (
SELECT
LEFT(@Code, CHARINDEX(', ', @Code) - 1),
SUBSTRING(@Code, CHARINDEX(', ', @Code) + 2, DATALENGTH(@Code))

UNION ALL

SELECT
CASE
WHEN CHARINDEX(', ', p.rght) = 0 THEN p.rght
ELSE LEFT(p.rght, CHARINDEX(', ', p.rght) - 1)
END,
CASE
WHEN CHARINDEX(', ', p.rght) > 0 THEN SUBSTRING(p.rght, CHARINDEX(', ', p.rght) + 2, DATALENGTH(p.rght))
ELSE ''
END
FROM parser p
WHERE DATALENGTH(p.rght) > 0
)
SELECT * FROM @Temp WHERE Code IN (
SELECT lft FROM parser
)



اما این مساله ارتباطی به تعریف نوع فیلد نداره. در واقع شما چون ورودی رو بصورت لیستی از اعداد به Query میخواهید پاس کنید، حل مساله پیچیده شده و چاره ای به جز تبدیل اون لیست، به جدول و در نهایت استفاده از اون جدول باقی نمی مونه.

موفق باشید.

Sal_64
شنبه 13 مهر 1392, 12:23 عصر
سلام
تشکر
چطور باید از این کد در sp استفاده کرد
من داخل sp و پس از کلمه as این کد کپی کردم و قبل از کدهای تعریف تیبل موقت (که داخل sp به اون نیاز دارم)
اما ..

as


;WITH parser(lft, rght) AS (
SELECT
LEFT(@code_bodge, CHARINDEX(', ', @code_bodge) - 1),
SUBSTRING(@code_bodge, CHARINDEX(', ', @code_bodge) + 2, DATALENGTH(@code_bodge))

UNION ALL

SELECT
CASE
WHEN CHARINDEX(',', p.rght) = 0 THEN p.rght
ELSE LEFT(p.rght, CHARINDEX(', ', p.rght) - 1)
END,
CASE
WHEN CHARINDEX(', ', p.rght) > 0 THEN SUBSTRING(p.rght, CHARINDEX(', ', p.rght) + 2, DATALENGTH(p.rght))
ELSE ''
END
FROM parser p
WHERE DATALENGTH(p.rght) > 0

)



DECLARE @Tab TABLE
(

Incorrect syntax near the keyword 'DECLARE'.

و مورد بعد اینکه چرا یک اسپیس فاصله انداختین ، آیا دلیل خاصی داره


'12, 13, .5'
CHARINDEX(', ',

بارم ممنون

Sal_64
دوشنبه 15 مهر 1392, 12:36 عصر
سلام
همچنان مشتاقانه منتظر راهنمایی اساتید بزرگوار هستم

fakhravari
پنج شنبه 25 مهر 1392, 11:26 صبح
DECLARE @a VARCHAR(50)= N'.1;.5;1.1;1.5;';

WITH MyWords (ranking, word, string )
AS (
SELECT
1
, CAST(SUBSTRING(@a , 1 , CHARINDEX(';' , @a) - 1) AS VARCHAR(25))
, STUFF(@a , 1 , CHARINDEX(';' , @a) , '')
UNION ALL
SELECT
ranking + 1
, CAST(SUBSTRING(string , 1 , CHARINDEX(';' , string) - 1) AS VARCHAR(25))
, STUFF(string , 1 , CHARINDEX(';' , string) , '')
FROM
MyWords
WHERE
CHARINDEX(';' , string) > 0
)
SELECT [id],[name]FROM [Table_1] WHERE [id] IN(SELECT word FROM MyWords)

Sal_64
پنج شنبه 25 مهر 1392, 11:55 صبح
سلام بر مهندس وظیفه
آقا ممنون
اما مشکل من چیز دیگست
من میخوام این قطعه کد داخل یک sp قرار بدم
دقیقا کجا باید بذارم که خطا نگیره
من اینو مابین as و اولین دستوران sp قرار میدم که خطا میگیره


as
WITH MyWords (ranking, word, string )
AS (
SELECT
1
, CAST(SUBSTRING( @code_bodge , 1 , CHARINDEX(';' , @code_bodge) - 1) AS VARCHAR(25))
, STUFF( @code_bodge , 1 , CHARINDEX(';' , @code_bodge) , '')
UNION ALL
SELECT
ranking + 1
, CAST(SUBSTRING(string , 1 , CHARINDEX(';' , string) - 1) AS VARCHAR(25))
, STUFF(string , 1 , CHARINDEX(';' , string) , '')
FROM
MyWords
WHERE
CHARINDEX(';' , string) > 0
)

DECLARE @Tab TABLE
(


Incorrect syntax near the keyword 'DECLARE'.

fakhravari
پنج شنبه 25 مهر 1392, 12:27 عصر
CREATE PROCEDURE GetList
AS
DECLARE @a VARCHAR(50)= N'.1;.5;1.1;1.5;';
WITH MyWords (ranking, word, string )
AS (
SELECT
1
, CAST(SUBSTRING(@a , 1 , CHARINDEX(';' , @a) - 1) AS VARCHAR(25))
, STUFF(@a , 1 , CHARINDEX(';' , @a) , '')
UNION ALL
SELECT
ranking + 1
, CAST(SUBSTRING(string , 1 , CHARINDEX(';' , string) - 1) AS VARCHAR(25))
, STUFF(string , 1 , CHARINDEX(';' , string) , '')
FROM
MyWords
WHERE
CHARINDEX(';' , string) > 0
)
SELECT [id],[name]FROM [Table_1] WHERE [id] IN(SELECT word FROM MyWords)

fakhravari
پنج شنبه 25 مهر 1392, 12:27 عصر
CREATE PROCEDURE GetList
AS
DECLARE @a VARCHAR(50)= N'.1;.5;1.1;1.5;';
WITH MyWords (ranking, word, string )
AS (
SELECT
1
, CAST(SUBSTRING(@a , 1 , CHARINDEX(';' , @a) - 1) AS VARCHAR(25))
, STUFF(@a , 1 , CHARINDEX(';' , @a) , '')
UNION ALL
SELECT
ranking + 1
, CAST(SUBSTRING(string , 1 , CHARINDEX(';' , string) - 1) AS VARCHAR(25))
, STUFF(string , 1 , CHARINDEX(';' , string) , '')
FROM
MyWords
WHERE
CHARINDEX(';' , string) > 0
)
SELECT [id],[name]FROM [Table_1] WHERE [id] IN(SELECT word FROM MyWords)


برای تست EXEC GetList

tooraj_azizi_1035
جمعه 26 مهر 1392, 16:03 عصر
راه دیگه ساخت تابع Split در SQL هست:

create function dbo.SplitString
(
@str nvarchar(4000),
@separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
select
1,
1,
charindex(@separator, @str)
union all
select
p + 1,
b + 1,
charindex(@separator, @str, b + 1)
from tokens
where b > 0
)
select
p-1 zeroBasedOccurance,
substring(
@str,
a,
case when b > 0 then b-a ELSE 4000 end)
AS s
from tokens
)
GO


declare @code varchar(max)
set @code='10,20,30,80,0.6'

select * from table where code in (dbo.SplitString(@code,','))

Sal_64
جمعه 26 مهر 1392, 21:00 عصر
سلام
بعد از تعریف تابع و در زمان استفاده این ایرور میده

Cannot find either column "dbo" or the user-defined function or aggregate "dbo.SplitString", or the name is ambiguous.

Sal_64
جمعه 26 مهر 1392, 22:52 عصر
پاسخ :

select * from table where code in (select s from dbo.SplitString(@code,','))

tooraj_azizi_1035
یک شنبه 28 مهر 1392, 17:34 عصر
پستم عجله ای بود.:اشتباه: