如何使用两个不同的查询编写存储过程

时间:2015-01-24 10:49:40

标签: c# sql-server stored-procedures

其实我是数据库的初学者.. 我编写了一个存储过程,我想在其中使用if else从两个不同的表中获取c#winform app中的结果,例如我有两个表,其中一个列是共同的,即' comp_number' ..现在我编写了一个在按钮点击事件上执行的存储过程

ALTER procedure [dbo].[complainVehicle_sp]
as
DECLARE @compno int


if @compno is not null  

begin

    select compno,compdate,regno,engineno,mcode from dbo.complainVehicle 
    where compno =  @compno 

end

else 

begin

   select compno,recoverydt,recoverytime,statuscode from dbo.complainRecovery
   where compno =  @compno   

end

现在我希望如果Compno与表complainVehicle匹配,它会向我显示结果,如果它与表complainRecovery匹配,它会向我显示针对该记录的结果,否则它将显示显示没有记录..

这是我的c#代码

  string str = @"Data Source=.;Initial Catalog=----;Integrated Security=False;User ID=sa;Password=----;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False;";
            SqlConnection cnn = null;


            try
            {
                cnn = new SqlConnection(str);
                cnn.Open(); //open the connection

            }


            catch (SqlException err) 
            {
                Console.WriteLine("Error: " + err.ToString());
            }
            finally
            {
                if (cnn != null)
                {
                    cnn.Close(); 
                }
            } 


            if (textBox1.Text.Trim().Length == 0)

            {MessageBox.Show("No Record");}

            else if (textBox1.Text.Trim().Length  > 0)  
            {

                cnn.Open();
                SqlCommand cmd2 = new SqlCommand();
                cmd2.Connection = cnn;
                cmd2.CommandType = CommandType.StoredProcedure;
                cmd2.CommandText = "complainVehicle_sp";
                cmd2.Parameters.Add("@compno", System.Data.SqlDbType.NVarChar).Value = textBox1.Text.ToString();
                cmd2.ExecuteNonQuery();
                SqlDataAdapter da = new SqlDataAdapter(cmd2);
                DataSet ds = new DataSet();
                da.Fill(ds);
                dataGridView1.DataSource = ds.Tables[0];
                cnn.Close();

当我在文本框中编写compno并单击sumbit时,它会显示错误 `类型&System; System.Data.SqlClient.SqlException'的未处理异常发生在System.Data.dll

附加信息:程序complainVehicle_sp没有提供参数和参数。

...我非常感谢大家的帮助..先谢谢你们

2 个答案:

答案 0 :(得分:1)

在您的代码中使用DECLARE @compno int,它在过程体中创建一个局部变量。无法从存储过程上下文外部访问@compno变量,它对调用该过程的C#代码没有任何意义:

cmd2.Parameters.Add(
    "@compno", 
    System.Data.SqlDbType.NVarChar).Value = textBox1.Text.ToString();

因此,要解决您的问题,请先将存储过程更改为接受参数

ALTER PROCEDURE [dbo].[complainVehicle_sp]
-- declare a parameter @compono to the procedure
    @compno INT
as ...
BEGIN
    IF @compno IS NOT NULL
    BEGIN
        SELECT compno,compdate,regno,engineno,mcode 
        FROM dbo.complainVehicle 
        WHERE compno = @compno 
    END
    ELSE
    BEGIN
        SELECT compno,recoverydt,recoverytime,statuscode 
        FROM dbo.complainRecovery
        WHERE compno =  @compno   
    END
END

其次,您必须在C#代码中添加适当的参数类型:

cmd2.Parameters.Add(
    "@compno", 
    System.Data.SqlDbType.Int).Value = int.Parse(textBox1.Text);

由于参数在存储过程定义中声明为INT,因此您需要使用System.Data.SqlDbType.Int并通过调用int.Parse(textBox1.Text)提供有效的整数值。

有关创建存储过程和参数选项的更多信息,请参阅T-SQL Stored Procedure Syntax

答案 1 :(得分:0)

首先,您必须使用参数声明您的过程,然后您可能希望使用EXISTS来检查每个表,如下所示;

alter procedure [dbo].[complainVehicle_sp] (@compno int)
as

if (exists (select 1 from dbo.complainVehicle where compno = @compno ) )
begin
    select compno,compdate,regno,engineno,mcode from dbo.complainVehicle 
    where compno =  @compno 
end
else
if (exists (select 1 from dbo.complainRecovery where compno = @compno ) )
begin
   select compno,recoverydt,recoverytime,statuscode from dbo.complainRecovery
   where compno =  @compno   
end

您还需要正确指定参数的类型;

cmd2.Parameters.Add("@compno", System.Data.SqlDbType.Int).Value = textBox1.Text.ToString();