1

这是我的SP。我收到此错误 - “子查询返回的值超过 1 个。当子查询遵循 =、!=、<、<=、>、>= 或将子查询用作表达式时,这是不允许的。”

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 + ''') 

我只为不同的客户端 ID(1566 和 1697)获取第一条记录的计数。(参考图片) 在此处输入图像描述

在 ClientID=1566 的第 45 条记录(1566 的总行数为 45)之后,我希望更改 ClientID=1697(即 63)的计数。我不知道如何处理这个问题。我是新手。请帮忙。

4

2 回答 2

3

那里有一些猜测工作,但是,SQL 注入不是你的朋友。那需要去,现在。因此,我改用了表类型参数。

关于错误,这是由于以下声明:

(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
于 2018-07-20T07:58:00.153 回答
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
于 2018-07-20T08:04:59.010 回答