如何将记录集作为输出参数返回?

时间:2011-11-27 00:52:07

标签: c# tsql ado.net

我正在调用应该删除记录的存储过程。在删除之前,如果另一个表中有任何记录涉及我们要删除的记录,则执行检查。如果是,我需要返回一个文本值列表,用于标识引用我们要删除的记录的记录,以便用户可以先删除它们。我想我应该使用输出参数,但不知道如何为它分配记录集。这是我的代码:

            SqlCommand cmd = new SqlCommand("DeleteTD", conn);

            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@pID", gvTD.SelectedDataKey));
            SqlParameter resultParameter = cmd.Parameters.Add(new SqlParameter("@pResult", SqlDbType.NVarChar));
            resultParameter.Direction = ParameterDirection.Output;
            rdr = cmd.ExecuteReader();

我不确定我的resultParameter是否正确。 以下是存储过程的一部分:

CREATE PROCEDURE DeleteTD
    -- Add the parameters for the stored procedure here
    @pID INT, 
    @pResult NVARCHAR(100) OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here

    DECLARE @vCount INT;

    SELECT @pResult = 0;
    SELECT @vCount = COUNT(1) FROM Город WHERE Город.ТД = '@pID';

    IF @vCount > 0
        SELECT @pResult = Название FROM Город WHERE ТД = '@pID';
    ELSE
        DELETE FROM ТД WHERE ID = @pID;

同样,我不确定@pResult应该具有什么类型。

你能帮我写一下正确的代码吗? 谢谢, 大卫

2 个答案:

答案 0 :(得分:3)

目前SP的问题在于,您只会获得一个返回值,而不是一个值列表。

您有三种选择:

1)向用户返回1值,表示有问题的第一条记录。这是最容易实现的。

 SELECT TOP 1 @pResult = Название FROM Город WHERE ТД = '@pID';

在这种情况下,@ pResult的大小应为Название。

2)将所有值返回给用户,指示参数中的完整问题列表。如果值太多,这将成为SQL和用户的问题。

 SELECT @pResult = CASE WHEN @pResult <> '' THEN ', ' ELSE '' END + Название FROM Город WHERE ТД = '@pID';

这将返回以逗号分隔的列表。在这种情况下,如果您的数据库支持,则@pResult应为NVARCHAR(MAX)或NVARCHAR(8000)。在任何一种情况下,你都应该考虑将这个陈述限制在前n个(比如10个匹配)。

3)使用标准select语句将所有值返回给用户。

 SELECT Название FROM Город WHERE ТД = '@pID';

在这种情况下,您的代码必须使用ExecuteReader而不是ExecuteNonQuery,并且不需要@pResult。

至于使用@pResult的正确方法:

对于前两个选项,请更改以下行:

rdr = cmd.ExecuteReader();

为:

cmd.ExecuteNonQuery();

string sError;
if (resultParameter.Value != DBNull.Value) {
    sError = resultParameter.Value.ToString();

if (!string.IsNullOrEmpty(sError) {
  // Report the error to the user.

在第三种情况下,您将完全删除参数代码并只处理读取器输出(粗略代码如下):

rdr = cmd.ExecuteReader();

StringBuilder sbResult = new StringBuilder(500);

do while rdr.Read() {
   if (sbResult.Length != 0) {
      sbResult.Append(", ");
   }
   sbResult.Append(rdr[0].ToString());
}

答案 1 :(得分:3)

我会考虑摆脱@pResult。

将其更改为......

的陈述

如果计数&gt; 0 从另一个表中选择id = @pId

否则 删除 return null

然后在代码中完成对null的检查..否则你将获得与@pId相关的记录列表

保重,

的Brynn