【问题标题】:Return values from SQL Server stored procedure从 SQL Server 存储过程返回值
【发布时间】:2017-09-18 19:47:34
【问题描述】:

我在 SQL Server 中有一个存储过程,它返回两个值。当使用以下 SQL 代码从 QA 调用时:

exec TWEEPush_ValidateCO @CoFilter='CO IN(''1502'',''Mike'',''Clarkson'')', @TDate='09/18/`2017'

它通过返回两个值按预期工作:

@TempCOID   @TempDate  
1502        09/10/2017

存储过程做了一些工作,并以将两个值设置为非空值结束,存储过程以:

SELECT 
    @TempCOID AS N'@TempCOID',  
    @TempDate AS N'@TempDate'

在 VB.net(Visual Basic,而不是 C)中,我尝试了许多不同的方法来获得结果,但都没有运气。要么我得到一个错误,说命名的参数不存在,要么它最终返回空值(一切都被编码以防止返回数据中出现 Null)

Dim sConnectStr As String = GetSQLConnectionString()

Try
    Using Connection As New SqlConnection(sConnectStr)
        Connection.Open()

        Dim Command As New SqlCommand("dbo.TWEEPush_ValidateCO", Connection)
        Command.CommandType = CommandType.StoredProcedure
        Command.Parameters.AddWithValue("@CoFilter", Filter)
        Command.Parameters.AddWithValue("@TDate", Now())

        Dim PramCOIDRet As New SqlParameter
        PramCOIDRet.ParameterName = "@TempCOID"
        PramCOIDRet.SqlDbType = SqlDbType.NVarChar
        PramCOIDRet.Size = 30
        PramCOIDRet.Direction = ParameterDirection.Output

        Dim PramDateRet As New SqlParameter
        PramDateRet.ParameterName = "@TempDate"
        PramDateRet.SqlDbType = SqlDbType.NVarChar
        PramDateRet.Size = 30
        PramDateRet.Direction = ParameterDirection.Output

        Command.Parameters.Add(PramCOIDRet)
        Command.Parameters.Add(PramDateRet)

        Command.ExecuteNonQuery()

        Dim COID as string = Command.Parameters("@TempCOID").Value
        Dim CoDate as Date = CDate(Command.Parameters("@TempDate").Value)
    End Using
Catch ex As Exception
End Try

无论我尝试过什么代码,代码都不会按预期返回数据。 我究竟做错了什么?有人能解释一下吗?

【问题讨论】:

  • 尽管使用了相当奇怪的列名,但这些“参数”实际上并不是参数。您只会得到一个正常的结果集,其中包含一行,其中包含值。您应该使用 ExecuteReader 而不是 ExecuteNonQuery(因为它实际上是一个查询;这就是 SELECT 正在做的事情),然后从那里获取结果。
  • 如果你检查PramDateRet.ValuePramCOIDRet.Value会怎样
  • 该过程看起来很可疑,就像它正在接收一个字符串并将其作为动态 sql 执行。这很可怕,很可能容易受到sql注入。
  • 这个代码被提供了一个由存储过程验证的公司 ID。如果公司 ID 被证明是有效的 ID,则返回有效的公司 ID(可能存在大小写问题,因此是公司 ID 的正式版本)和日期(存储在其他地方,此处需要)。我会看看是否可以将其作为单个查询重新处理。
  • 如果用动态 sql 验证它为时已晚。你真的在使用正确的参数。表值参数非常适合这类事情。

标签: sql-server vb.net tsql stored-procedures


【解决方案1】:

您没有向我们展示您的存储过程代码 - 但很可能是这样的:

CREATE PROCEDURE dbo.dbo.TWEEPush_ValidateCO
    @CoFilter VARCHAR(100),   -- just guessing here!
    @TDate DATE               -- again - just guessing 
AS
BEGIN
    DECLARE @TempCOID INT;
    DECLARE @TempDate DATE;

    -- do some calculations here that define @TempCOID and @TempDate
    -- this is just for demo purposes - I'm sure your calculation is a bit
    -- more complex and involved...
    SET @TempCOID = 1502;
    SET @TempDate = '20170910';

    -- return the values in a SELECT statement
    SELECT 
        @TempCOID AS N'@TempCOID',  
        @TempDate AS N'@TempDate'
END

在这种情况下,您返回一个结果集 - 不是两个参数!

你需要像这样得到你的价值观:

static void Main(string[] args)
{
    string connectionString = ConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString;

    int tempCoid;
    DateTime tempDate;

    using (SqlConnection conn = new SqlConnection(connectionString))
    using (SqlCommand cmd = new SqlCommand("dbo.dbo.TWEEPush_ValidateCO", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("@CoFilter", Filter);
        cmd.Parameters.AddWithValue("@TDate", DateTime.Now);

        conn.Open();

        using (var rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                tempCoid = rdr.GetFieldValue<int>(0);
                tempDate = rdr.GetFieldValue<DateTime>(1);
            }
        }

        conn.Close();
    }
}

(我相信您明白了 - 您也可以轻松地将其转换为 VB.NET)。

希望有帮助!

马克

【讨论】:

  • 马克;这与代码和 SQL proc 内部一样接近。可悲的是,我仍然没有得到价值。我今天没有时间解决很可能是我的编码错误(即不是你的例子)。在任何情况下,来自 SP 的返回值永远不会也永远不会为空。它们可以为空,但不能为空。
  • @RGS:除了那些 cmets 已经说过的话,我真的没有什么要说的了
  • 这在大部分情况下都有效;感谢您的洞察力。我不知道为什么我没有想到这一点。无论如何,谢谢!
猜你喜欢
  • 2020-12-11
  • 2010-11-23
  • 2015-10-06
  • 1970-01-01
  • 2016-11-03
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多