我想使用以下参数创建存储过程:@WorkspaceID int
我现在拥有的是:
DECLARE @WorkspaceRuleIds varchar(max)
SELECT @WorkspaceRuleIds = COALESCE(@WorkspaceRuleIds + ', ', '') +
CAST(RuleID AS varchar(5))
FROM Dgn_Workspace_Rules
WHERE WorkspaceID = @WorkspaceID;
SELECT ag.*
FROM Dgn_Rules ag
LEFT JOIN Dgn_Workspace_Rules wr ON ag.RuleID IN (@WorkspaceRuleIds)
WHERE wr.WorkspaceID = @WorkspaceID
如果@WorkspaceID
的值为25,那么ag.RuleID IN (80,82)
应该作为参数...但是我得到了这个错误
Msg 245,Level 16,State 1,Line 3
转换nvarchar值时转换失败' 80,82'数据类型int。
我该如何解决这个问题?谢谢!
答案 0 :(得分:4)
有几种众所周知的连接行值的技术。阅读Concatenating Row Values in Transact-SQL了解各自的优缺点。
ag.RuleID IN (@WorkspaceRuleIds)
这没有做任何接近你期望的事情。它不是宏观替代品。它是对标量值为IN
的{{1}}谓词的检查。因此,根据Data Type Precedence Rules,@WorkspaceRuleIds
将被强制转换为int。这会导致你看到的施法错误。
您的查询完全没有意义。在IN情况下加入?
从不在SQL中使用逗号分隔列表。的 NEVER 强>
答案 1 :(得分:0)
尝试以下查询
SELECT
ag.*
FROM Dgn_Rules AS ag
LEFT JOIN Dgn_Workspace_Rules AS wr ON wr.RuleID = ag.RuleID
WHERE wr.WorkspaceID = @WorkspaceID
答案 2 :(得分:0)
谢谢你们的帮助,但是......我找到了一个问题的答案。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX))
RETURNS @TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET @InStr = REPLACE(@InStr + ',', ',,', ',')
DECLARE @SP INT
DECLARE @VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', @INSTR ) <> 0
BEGIN
SELECT @SP = PATINDEX('%,%',@INSTR)
SELECT @VALUE = LEFT(@INSTR , @SP - 1)
SELECT @INSTR = STUFF(@INSTR, 1, @SP, '')
INSERT INTO @TempTab(id) VALUES (@VALUE)
END
RETURN
END
GO
然后执行:
DECLARE @WorkspaceRuleIds varchar(max)
SELECT @WorkspaceRuleIds = COALESCE(@WorkspaceRuleIds + ', ', '') +
CAST(RuleID AS varchar(5))
FROM Dgn_Workspace_Rules
WHERE WorkspaceID = @WorkspaceID;
SELECT
ag.*
FROM
Dgn_Rules ag
LEFT JOIN
Dgn_Workspace_Rules wr
ON
ag.RuleID IN (SELECT * FROM dbo.CSVToTable(@WorkspaceRuleIds))
WHERE
wr.WorkspaceID = @WorkspaceID
它完全输出我需要的东西。