这是我的SP。 我收到此错误-“子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =或当子查询用作表达式时,不允许这样做。” >
enter code here
ALTER PROCEDURE GetToDoDetails
@ClientID VARCHAR(MAX) = NULL
AS
DECLARE @Sql VARCHAR(MAX)
SET @ClientID = REPLACE(@ClientID,',',''',''')
SET @Sql=
'SELECT
C.ClientID,
C.ClientToDoID,
C.AssignedToID,
C.ToBeCompletedBy,
C.ToDoTypeID,
S.UDDescription,
(CL.LastName +'',''+ CL.FirstName) "Client Name",
(Select count(ClientID) from c_ToDo WHERE ClientID IN (''' + @ClientID+''') GROUP BY ClientID) "CountRow"
FROM c_ToDo C
INNER JOIN s_UserDefinedOptions S ON C.ToDoTypeID = S.UDID
INNER JOIN c_Client CL ON C.ClientID = CL.ClientID
WHERE
C.ClientID IN (''' + @ClientID + ''')
ORDER BY C.ClientID ASC'
EXEC (@Sql)
GO
如果我写
EXEC GetToDoDetails '1566'
,我得到这个结果(参考图片)
现在如果我写
EXEC GetToDoDetails '1566,1697'
它显示了我所讲述的错误。 在子查询中将TOP 1添加为
之后(Select TOP 1 count(ClientID) from c_ToDo WHERE ClientID IN (''' + @ClientID + ''')
我仅针对不同的clientID(1566和1697)获得第一条记录的计数。(请参阅图片)
ClientID = 1566的第45条记录之后(1566的总行数为45), 我希望为ClientID = 1697(即63)更改计数。 我不知道该如何处理。我是新手。请帮忙。
答案 0 :(得分:3)
其中存在一些猜测,但是SQL Injection不是您的朋友。现在需要走了。因此,我改用了表类型参数。
关于错误,这是由于以下原因引起的:
(Select count(ClientID) from c_ToDo WHERE ClientID IN (''' + @ClientID+''') GROUP BY ClientID) "CountRow"
如果您在@ClientID
中有多个值,它将返回多行。另外,SQL Server中对象的引号运算符是括号([]
),而不是双引号("
)。
无论如何,这是一个猜测,但这应该可以使您走上正确的道路(我希望如此):
CREATE TYPE ClientList AS TABLE (ClientID int); --Datatype is GUESSED
GO
CREATE PROCEDURE GetToDoDetails @Client ClientList READONLY
AS
SELECT C.ClientID,
C.ClientToDoID,
C.AssignedToID,
C.ToBeCompletedBy,
C.ToDoTypeID,
S.UDDescription,
(CL.LastName + ',' + CL.FirstName) AS [Client Name],
COUNT(C.ClientID) OVER (PARTITION BY C.ClientID) AS [CountRow] --Total guess here
--If this is meant to just be a count of EVERY row, remove the PARTITION BY clause (so just OVER())
FROM c_ToDo C
INNER JOIN s_UserDefinedOptions S ON C.ToDoTypeID = S.UDID
INNER JOIN c_Client CL ON C.ClientID = CL.ClientID
WHERE EXISTS (SELECT 1 FROM @Client e WHERE C.ClientID = e.ClientID) --Changed from IN to EXISTS
ORDER BY C.ClientID ASC;
GO
答案 1 :(得分:0)
在select语句中有一个用于计数的子查询是不理想的,在您的查询中您将获得多个值,因为client id
具有多个值,我希望将其放在join语句中。 Print @sql
应该可以检查语句是否有效。这将为您解决问题
DECLARE @ClientID VARCHAR(MAX) = NULL
DECLARE @Sql VARCHAR(MAX)
SET @ClientID = REPLACE('1566,1697,2467',',',''',''')
SET @Sql=
'SELECT
C.ClientID,
C.ClientToDoID,
C.AssignedToID,
C.ToBeCompletedBy,
C.ToDoTypeID,
S.UDDescription,
(CL.LastName +'',''+ CL.FirstName) "Client Name",
"CountRow"
FROM c_ToDo C
INNER JOIN s_UserDefinedOptions S ON C.ToDoTypeID = S.UDID
INNER JOIN c_Client CL ON C.ClientID = CL.ClientID
INNER JOIN (Select count(*) CountRow,ClientID from c_ToDo WHERE ClientID IN (''' + @ClientID+''') GROUP BY ClientID) CO
on C.ClientID = CO.ClientID
WHERE
C.ClientID IN (''' + @ClientID + ''')
ORDER BY C.ClientID ASC'
PRINT (@Sql)
您的SP:
ALTER PROCEDURE GetToDoDetails
@ClientID VARCHAR(MAX) = NULL
AS
BEGIN
DECLARE @Sql VARCHAR(MAX)
SET @ClientID = REPLACE(@ClientID,',',''',''')
SET @Sql=
'SELECT
C.ClientID,
C.ClientToDoID,
C.AssignedToID,
C.ToBeCompletedBy,
C.ToDoTypeID,
S.UDDescription,
(CL.LastName +'',''+ CL.FirstName) "Client Name",
"CountRow"
FROM c_ToDo C
INNER JOIN s_UserDefinedOptions S ON C.ToDoTypeID = S.UDID
INNER JOIN c_Client CL ON C.ClientID = CL.ClientID
INNER JOIN (Select count(*) CountRow,ClientID from c_ToDo WHERE ClientID IN (''' + @ClientID+''') GROUP BY ClientID) CO
on C.ClientID = CO.ClientID
WHERE
C.ClientID IN (''' + @ClientID + ''')
ORDER BY C.ClientID ASC'
PRINT (@Sql)
EXEC (@Sql)
END