【问题标题】:Retrieve value from stored procedures in a C# Windows App从 C# Windows 应用程序中的存储过程中检索值
【发布时间】:2011-10-20 08:16:48
【问题描述】:

我正在尝试在 C# WPF 应用程序中显示存储过程返回的值。用户输入他们的卡号,点击“提交”,然后运行以下代码:

if (textBox1.Text != "")
{
    long numCardNumber; //Card number (card number scanned and converted to a number)
    string strCardNumber; // Card number (card number stored as string)
    char[] MyChar = {';','?'};

    label2.Text = textBox1.Text.TrimEnd(MyChar); // Trims end
    label2.Text = label2.Text.TrimStart(MyChar); //Trims beginning

    strCardNumber = label2.Text; 

    try //try and convert the string to a number (if valid numerical characters
    {
        numCardNumber = Convert.ToInt64(strCardNumber);
        label1.Text = "Your number is: " + label2.Text; // Scanned " + numOfTimeScanned + " times"; 


    }
    catch(FormatException) // thrown if input characters are not valid numeric
    {
        label1.Text = "NOT A VALID CARD INPUT!";
    }

    SqlConnection connection = new SqlConnection("Data Source=TestServer;Initial Catalog=Testdb;Persist Security Info=True;User ID=testuser;Password=testpass");

    connection.Open();
    SqlCommand cmd = new SqlCommand("GW_MAGTOOCR", connection);
    cmd.CommandType = CommandType.StoredProcedure;

    SqlParameter param = new SqlParameter("@iMAG", SqlDbType.Char);
    param.Value = label1.Text;
    cmd.Parameters.Add(param);

    SqlParameter retval = cmd.Parameters.Add("@iMAG", SqlDbType.VarChar);
    retval.Direction = ParameterDirection.Output;

    int returnvalue = (int)cmd.Parameters["@iMAG"].Value;


} //END IF
else
{
    label1.Text = "Nothing Submitted!";
}

以下是涉及的 2 个存储过程。应该返回一个整数

名为 GW_MAGTOOCR 的存储过程 1 从代码中调用(代码又调用名为 CDS_INTTOHEX 的存储过程 2)。

存储过程 1:

USE [Testdb]
GO
/****** Object:  StoredProcedure [dbo].[GW_MAGTOOCR]  */
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER procedure [dbo].[GW_MAGTOOCR](
  @iMag char(18),
  @oOCR varchar(10) output
)
--WITH ENCRYPTION
as

declare
  @vTStr   varchar(9),
  @vPrefix char(2),
  @vCRC    varchar(2),
  @vTemp   int
begin
  IF isnumeric(@iMag) = 0
    Begin
      Set @oOcr = Null
      Return
    End
  -- get the prefix
  select @vTemp = convert(int, substring(@iMag, 4, 3))
  execute CDS_INTTOHEX @vTemp, @vTStr output
  select @vPrefix = substring(@vTStr, 7, 2)
  -- get the CRC
  select @vTemp = convert(int, substring(@iMag, 7, 2))
  execute CDS_INTTOHEX @vTemp, @vTStr output
  select @vCRC = substring(@vTStr, 8, 1)
  select @vTemp = convert(int, substring(@iMag, 9, 2))
  execute CDS_INTTOHEX @vTemp, @vTStr output
  select @vCRC = @vCRC + substring(@vTStr, 8, 1)
  -- get the account #
  select @vTemp = convert(int, substring(@iMag, 11, 8))
  execute CDS_INTTOHEX @vTemp, @vTStr output
  select @oOCR = @vPrefix + @vCRC + substring(@vTStr, 3, 6)
 /*select output = @vPrefix + @vCRC + substring(@vTStr, 3, 6)*/
end

存储过程 2:

USE [Testdb]
GO
/****** Object:  StoredProcedure [dbo].[CDS_INTTOHEX]  *****/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER procedure [dbo].[CDS_INTTOHEX] (
  @iInteger   int,
  @oHex       varchar(9) output
) 
--WITH ENCRYPTION
as begin

  declare
    @vDec       int,
    @vHex       char,
    @vLen       int,
    @vDivisor   int,
    @vQuotient  int,
    @vRemainder int,
    @vTemp      varchar(9)
  select @vTemp = ''
  select @vQuotient = @iInteger
  select @oHex      = ''
  select @vLen      = 8
  while  @vLen > 0 begin
    select  @vLen = @vLen - 1
    select  @vDivisor = power(16, @vLen)
    select  @vDec = floor(@vQuotient / @vDivisor)
    if      @vDec < 10 select @vHex =convert(char, @vDec)
    else if @vDec = 10 select @vHex = 'A'
    else if @vDec = 11 select @vHex = 'B'
    else if @vDec = 12 select @vHex = 'C'
    else if @vDec = 13 select @vHex = 'D'
    else if @vDec = 14 select @vHex = 'E'
    else if @vDec = 15 select @vHex = 'F'
    select @vTemp = @vTemp + @vHex
    select  @vQuotient = @vQuotient - (@vDec * @vDivisor)
  end
  select @oHex = @vTemp
end

任何帮助将不胜感激。我很确定问题出在我的 C# 代码中,因为我可以从 SQL 管理工作室中成功调用存储过程并接收回预期值。

编辑

我已经稍微更新了我的代码,我创建了一个简单的存储过程,它基本上调用了前两个(最初是 MAGTOOCR),当我从 Management Studio 运行它时它似乎运行良好,现在我只是不确定如果我的代码调用正确,这是我更新的代码:

connection.Open();
            SqlCommand cmd = new SqlCommand("CNBID", connection);
            cmd.CommandType = CommandType.StoredProcedure;

            SqlParameter param = cmd.Parameters.Add("@iMAG", SqlDbType.Char, 18); 
            param.Direction = ParameterDirection.Output;
            param.Value = label2.Text;

            SqlDataReader rdr = cmd.ExecuteReader();

            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    label2.Text = "Reading";
                }
            }
            else
            {
                label2.Text = "NOTHING READ!";
            }

我知道代码最后没有输出任何有用的东西,但我想在调试时观察变量。我确定我在上面做的不对。再次感谢任何帮助。

【问题讨论】:

    标签: c# stored-procedures


    【解决方案1】:

    如果想让程序输出@iMAG的值,需要将参数方向设置为Output

    SqlParameter parm = cmd.Parameters.Add( "@iMAG", SqlDbType.Char);
    parm.Direction = ParameterDirection.Output;
    

    编辑

    您在代码中创建了两次@iMAG 参数。只需创建一次,如下所示:

    SqlParameter param = cmd.Parameters.Add("@iMAG", SqlDbType.VarChar); 
    param.Direction = ParameterDirection.Output
    param.Value = label1.Text; 
    

    【讨论】:

    • 感谢詹姆斯的意见。我相信这就是我目前正在做的事情,不确定是否还有其他方法可以解决?
    • 您创建了两次参数,并且没有为第二个 @iMAG 参数设置值。请参阅我编辑的答案。
    • 再次感谢您的回复和建议。 :-) 不确定我如何将值传递给存储过程。我需要传递一个 18 个字符的 int 以便存储过程返回一些东西。我会用 Parameters.Add 语句传递那个值吗?
    • 看我回答中的第二个例子。它将参数添加到命令对象,将其标记为输出参数,并为参数赋值。
    • 为什么是整数?你在计算它吗?此外,我没有在您发布的代码中看到您实际执行存储过程的位置。您需要在某个地方调用 ExecuteReader 或 ExecuteScalar。您的存储过程似乎没有选择或返回任何内容。
    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    相关资源
    最近更新 更多