How do I split a string so I can access item x?-解决方案使用了CTE
和WHILE
。我告诉我我的请求未使用WHILE,因为这不是很好的性能,它会延迟速度。.CURSOR
我正在使用SQL Server2012。我将获得一串ID(@IDs
),需要针对一个值(在本例中为1)进行测试。
IF (SELECT CycleId
FROM TABLE1
WHERE ID in (@IDs) ) = '1'
BEGIN
-- ABORT TRANSACTION AND FINISH THE QUERY
END
ELSE
BEGIN
-- START TRANSACTION FOR THE Id....
END
这不起作用。有人告诉我应该避免使用WHILE
或CURSOR
。
我需要运行@Ids中存在的几个值(可以是100个值,也可以是5个值,用逗号分隔)。如果这些ID中至少有一个具有CycleId = 1,则应完全停止该操作。也许是...
BEGIN
RAISERROR ('It is not possible to complete the transaction.',20,1)
BREAK
END
第一种情况:
@IDs = 121, 434, 543, 345
Id CycleId
---------------
121 1
434 2
543 1
345 1
在这种情况下,该操作应在@Id 121处停止(它不应读取/测试任何其他ID,并且应引发如我之前所示的错误)
第二种情况
@IDs = 121, 434, 543, 345
Id CycleId
--------------
121 3
434 2
543 5
345 6
在这种情况下,操作应该执行事务。
谢谢!
答案 0 :(得分:2)
假设您的字符串变量@ids
看起来像这样:' 2, 4 , 5 , 7,8,9,10, 21,22'
,则可以尝试以下操作:
-- pre-condition @ids by removing blanks and adding a comma at either end:
select @ids=','+replace(@ids,' ','')+',';
IF (SELECT 1 FROM TABLE1 WHERE patindex(concat('%,',CycleId,',%',@ids)>0 )
BEGIN
-- ABORT TRANSACTION AND FINISH THE QUERY
END
ELSE
BEGIN
-- START TRANSACTION FOR THE Id....
END
答案 1 :(得分:1)
您的第一个问题是,您正在尝试匹配以逗号分隔的值的VARCHAR列表内的整数。该 有一个解决方案,但是您应该指定一个表变量而不是CSV :
SELECT 1
FROM table1
WHERE CONCAT(',', @IDs, ',') LIKE CONCAT('%,', ID , ',%')
AND CycleId = 1
将以上内容包装在EXISTS子句中:
IF EXISTS (SELECT ...)
BEGIN
RAISERROR ...
END
答案 2 :(得分:1)
您可以尝试一下。
使用xml
节点以,
逗号溢出变量,然后获取结果集。
使用exists
比较条件。
declare @IDs varchar(100) = '121,434,543,345'
create table TABLE1(
Id int,
CycleId int
);
insert into TABLE1 values (121,1);
insert into TABLE1 values (434,2);
insert into TABLE1 values (543,1);
insert into TABLE1 values (345,1);
IF exists(
SELECT 1
FROM TABLE1 t1
WHERE ID in (
SELECT Split.a.value('.', 'NVARCHAR(MAX)')
FROM
(
SELECT CAST('<X>'+REPLACE(@IDs, ',', '</X><X>')+'</X>' AS XML) AS String
) AS A
CROSS APPLY String.nodes('/X') AS Split(a)
WHERE t1.CycleId = 1
)
)
BEGIN
-- ABORT TRANSACTION AND FINISH THE QUERY
END
ELSE
BEGIN
-- START TRANSACTION FOR THE Id....
END
答案 3 :(得分:0)
上:
使用Sik.D答案来完成剩余的操作..一个新的ID输入@ id = 4956且该表中不存在...因此t1.CycleId为NULL。重复很多次:
"SELECT Split.a.value('.', 'NVARCHAR(MAX)')
FROM ( SELECT CAST('<X>'+REPLACE(@IDs, ',', '</X><X>')+'</X>' AS XML) AS String) AS A
CROSS APPLY String.nodes('/X') AS Split(a))
”
这是最终代码:
IF exists(
SELECT 1
FROM TABLE1 t1
WHERE ID in (
SELECT Split.a.value('.', 'NVARCHAR(MAX)')
FROM
(
SELECT CAST('<X>'+REPLACE(@IDs, ',', '</X><X>')+'</X>' AS XML) AS String
) AS A
CROSS APPLY String.nodes('/X') AS Split(a)
WHERE t1.CycleId = 1
)
)
BEGIN -- there should be some ids without t1.CycleId -- assuming exists is true if there is one positive row for t1.CycleId=1
IF NOT EXISTS (SELECT 1
from table 1
where id in ( **-- same as before* WHERE t1.CycleId IS NULL) )
begin
INSERT INTO table1
values (id,1) -- not sure here with the Id...
end
ELSE
BEGIN
IF NOT EXISTS (SELECT 1
from table 1
where id in ( **-- same as before* WHERE t1.CycleId IS NULL) )
BEGIN
INSERT INTO table1
values (id,1) -- not sure here with the Id...
END
ELSE
BEGIN
UPDATE table1
SET CycleId=1
WHERE ID IN (SELECT Split.a.value('.', 'NVARCHAR(MAX)')
FROM ( SELECT CAST('<X>'+REPLACE(@IDs, ',', '</X><X>')+'</X>' AS XML) AS String) AS A
CROSS APPLY String.nodes('/X') AS Split(a))
END
END
如何简化?谢谢。