【问题标题】:Returning multiple values from a SQL Server stored procedure从 SQL Server 存储过程返回多个值
【发布时间】:2015-10-06 01:02:44
【问题描述】:

我想做的是使用我的spLogin 存储过程从同一个表中返回两个值,我想将这两个值都保存在 C# 中的会话中。

这是桌子

create table tbClients
(
    ClientID int primary key identity(0,1),
    ClientFirstName varchar(20),
    ClientLastName varchar(20),
    ClientAddress varchar(60),
    ClientOrigin varchar(20),
    ClientUsername varchar(20),
    ClientPassword int,
    ClientSecurity int
)

当客户端单击登录按钮时,我想编写一个程序来检查用户是否有效、他们的安全级别是什么以及他们的名字是什么。

这是我目前所拥有的

create procedure spLogin(
    @ClientUsername varchar(20),
    @ClientPassword int
)
AS BEGIN
    DECLARE @Security int
    DECLARE @ClientFirstName varchar(20)        

    IF EXISTS (SELECT * FROM tbClients 
               WHERE ClientUsername = @ClientUsername 
                 AND ClientPassword = @ClientPassword)
    BEGIN               
        SELECT 
            @Security = ClientSecurity, 
            @ClientFirstName = ClientFirstName 
        FROM tbClients 
        WHERE
            ClientUsername = @ClientUsername 
            AND ClientPassword = @ClientPassword

        IF(@Security = 1)
        BEGIN
            SELECT 'Admin' as Security, @ClientFirstName
        END
        ELSE
        BEGIN
            SELECT 'Customer' as Security, @ClientFirstName
        END
    END
    ELSE
    BEGIN
        SELECT 'INVALID'
    END
END
GO

不知道这是否可行,因为我不确定如何在不使用数据集的情况下将这些值存储在 C# 中,这似乎到目前为止还不起作用?

【问题讨论】:

  • 为什么不能用返回的值填充数据集?好吧,首先您的“无效”需要返回 2 个值,而不仅仅是一个。但是一旦解决了这个问题,您应该能够用存储过程结果填充数据集,然后读取数据集并在 C# 端进行处理。我自己已经做过很多次了。

标签: c# sql-server stored-procedures


【解决方案1】:

我会写这个过程有点不同,像这样.....

create procedure spLogin
    @ClientUsername     varchar(20)
   ,@ClientPassword     int
   ,@Security           VARCHAR(10)     OUTPUT
   ,@ClientFirstName    varchar(20)     OUTPUT
   ,@ValidLogin         INT             OUTPUT
AS 
BEGIN
  SET NOCOUNT ON;        

    IF EXISTS (SELECT * FROM tbClients 
               WHERE ClientUsername = @ClientUsername 
                 AND ClientPassword = @ClientPassword)
      BEGIN               
            SELECT @ValidLogin = 1 
                  ,@Security = CASE WHEN ClientSecurity = 1 
                                 THEN 'Admin' ELSE 'Customer' END
                  ,@ClientFirstName = ClientFirstName 
            FROM tbClients 
            WHERE ClientUsername = @ClientUsername 
              AND ClientPassword = @ClientPassword
      END
    ELSE
      BEGIN
            SET @ValidLogin = 0;
      END
END
GO

不是 C# 专家,但你会在 C# 中处理输出参数,例如......

// define connection and command, in using blocks to ensure disposal
using(SqlConnection conn = new SqlConnection(pvConnectionString ))
using(SqlCommand cmd = new SqlCommand("dbo.spLogin", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;

    // set up the input parameters
    cmd.Parameters.Add("@ClientUsername", SqlDbType.VarChar, 20);
    cmd.Parameters.Add("@ClientPassword", SqlDbType.Int);
    cmd.Parameters.Add("@Security", SqlDbType.VarChar, 10).Direction = ParameterDirection.Output;
    cmd.Parameters.Add("@ClientFirstName", SqlDbType.VarChar, 20).Direction = ParameterDirection.Output;
    cmd.Parameters.Add("@Success", SqlDbType.Int).Direction = ParameterDirection.Output;

    // set parameter values
    cmd.Parameters["@ClientUsername"].Value = UserNamTextbox.Text;

    // open connection and execute stored procedure
    conn.Open();
    cmd.ExecuteNonQuery();

    // read output value from @Security
    int Security = Convert.ToInt32(cmd.Parameters["@Security"].Value);

    if Security == 1 ....... and so on.......

    conn.Close();
}

【讨论】:

    【解决方案2】:

    所以我不能 100% 确定你有多少 C#,但这里是基础知识:

    使用此 SO 问题中的代码从 SQL Server 获取数据: Fill DataTable from SQL Server database

    然后,一旦你有了你的数据表,你就可以像这样使用 for 循环遍历它(假设你将数据表定义为“dt”):

    foreach (DataRow row in dt.Rows) 
    {
        //do what you need with your data.
        var value = row["ColumnName"];
        Console.WriteLine(value.ToString());
    }
    

    希望对您有所帮助。

    【讨论】:

    • 他的输出应该只返回1条记录,所以这个答案对OP的应用程序没有用。
    【解决方案3】:

    您的存储过程只返回一行的结果,您可以检查数据表中是否存在列:

    if (dt.columns.Contains("Security"))
    {
       ....
    }else{
       // Show error in fist row, fist column  
       return dt.Rows[0][0].ToString();
    }
    

    【讨论】:

      【解决方案4】:

      您可以执行存储过程并将结果填充到数据集中。

      每条select语句都会存储为一个数据表,你可以通过索引来访问对应的表。

      【讨论】:

      • 怎么办?你有什么例子吗?请。
      猜你喜欢
      • 1970-01-01
      • 2016-12-25
      • 2020-12-11
      • 2010-11-23
      • 2017-02-22
      • 1970-01-01
      • 2016-11-03
      • 2014-11-06
      • 1970-01-01
      相关资源
      最近更新 更多