代码之家  ›  专栏  ›  技术社区  ›  Chathuranga Chandrasekara

在C中使用存储过程#

  •  3
  • Chathuranga Chandrasekara  · 技术社区  · 15 年前

    我正在用C语言开发一个数据库应用程序。我有一个在表格上显示数据的要求,现在我已经完成了。但我的业务逻辑是硬编码到代码中的。现在,我想继续将存储过程与代码一起使用。我需要做什么修改。简单的步骤列表就足够了:)

    SqlConnection myConnection = new SqlConnection("user id=dbblabla;" + 
                "password=1234;server=localhost\\SQLEXPRESS;" + 
                "Trusted_Connection=yes;" + 
                "database=myDB; " + 
                "connection timeout=30");
    
    try
    {
        myConnection.Open();
    } catch (SqlException excep){
        Console.WriteLine(excep.StackTrace);
    }
    
    String selectionQuery = "SELECT * FROM myTable";
    SqlDataAdapter myAdapter = new SqlDataAdapter(selectionQuery,myConnection);
    
    DataSet ds = new DataSet();
    myAdapter.Fill(ds,"AllInfo");
    
    dataGridSearchOutput.DataSource = ds.Tables["AllInfo"].DefaultView;
    

    我从创建一个新的SQL命令开始,但我不确定是否使用了正确的方法。

    SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
    newCommand.CommandType = CommandType.StoredProcedure;
    
    10 回复  |  直到 7 年前
        1
  •  6
  •   KV Prajapati    15 年前

    存储过程

    CREATE PROCEDURE addemp
         @eno int,
         @ename varchar(50),
         @edate datetime
    AS
      declare @p int
    
      select @p=count(*) from emp
          where eno=@eno
      if @p=0
         begin
           insert into emp
             values (@eno,@ename,@edate)
         end        
        RETURN
    

    C码

        SqlConnection cn = new SqlConnection(@"conn_str");
        SqlCommand cmd = new SqlCommand("addemp", cn);
        cmd.CommandType = CommandType.StoredProcedure;
    
        cmd.Parameters.AddWithValue("@eno", 10);
        cmd.Parameters.AddWithValue("@ename", "Mr.Xyz");
        cmd.Parameters.AddWithValue("@edate", DateTime.Parse("1-1-2002"));
    
        cn.Open();
        cmd.ExecuteNonQuery();
        cn.Close();
    
        2
  •  5
  •   anishMarokey FIre Panda    15 年前

    存储过程

    CREATE PROCEDURE  procedure 
    
    AS
    BEGIN
    
        SET NOCOUNT ON;
        SELECT field1,field2 from tbl
    END
    GO
    

    代码

    using(SqlConnection con = new SqlConnection("user id=dbblabla;password=1234;server=localhost\\SQLEXPRESS; database=myDB; connection timeout=30"))
            {
                SqlCommand cmd = new SqlCommand("procedure",con);
                cmd.CommandType= System.Data.CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                da.Fill(dt);
                dataGridSearchOutput.DataSource = dt;           
    
            }
    

    为什么我用的是检查这个 link

        3
  •  2
  •   Navaneeth K N    15 年前

    只需将存储过程名称指定为 SQL命令 并设置 命令类型 命令类型.storedprocedure . 此外,将一次性物品包装在 使用 阻止。sqlconnection、sqlcommand和sqladapter是可释放的对象。这是一个修改过的代码。

    string connectionString = "user id=dbblabla;" + 
                            "password=1234;server=localhost\\SQLEXPRESS;" + 
                            "Trusted_Connection=yes;" + 
                            "database=myDB; " + 
                            "connection timeout=30";
    DataSet ds = new DataSet();
    using(SqlConnection myConnection = new SqlConnection(connectionString))
    using (SqlCommand command = new SqlCommand("yourprocedure", myConnection))
    {
        SqlDataAdapter myAdapter = new SqlDataAdapter();
        myAdapter.SelectCommand = command;
        myAdapter.Fill(ds,"AllInfo");
    }
    dataGridSearchOutput.DataSource = ds.Tables["AllInfo"].DefaultView;
    
        4
  •  2
  •   JBrooks    15 年前

    我不明白为什么人们在数据访问代码方面忘记了他们使用的是面向对象的语言。您不应该一遍又一遍地编写相同的代码。首先,您应该有一个在所有项目中使用的基类。这个基类应该处理连接字符串、日志异常等。我在一年前写的,从那以后就没有太大的改变。

    请查看以下示例以了解将在此基类中的示例:

    protected SqlCommand GetNewCmd()
    {
        SqlCommand objCmd = new SqlCommand();
        objCmd.Connection = new SqlConnection(this.ConnString);
        objCmd.CommandType = CommandType.StoredProcedure;
        return objCmd;
    
    }
    
    protected SqlCommand GetNewCmd(string CmdText)
    {
        SqlCommand objCmd = new SqlCommand(CmdText, 
                                 new SqlConnection(this.ConnString));
        objCmd.CommandType = CommandType.StoredProcedure;
        return objCmd;
    }
    
    protected DataTable GetTable(SqlCommand objCmd)
    {
        DataTable dt = new DataTable();
        SqlDataAdapter da = new SqlDataAdapter();
    
        try
        {
            da.SelectCommand = objCmd;
            da.Fill(dt);
    
            dt.DefaultView.AllowNew = false;
        }
        catch (Exception ex)
        {
            LogException(ex);
            throw;
        }
        finally
        {
            Close(objCmd);
            da.Dispose();
            da = null;
    
        }
    
        return dt;
    
    }
    

    我们有gettable()、getdataset()、executescalarint()、executescalarguid()等,每个都有一系列重载。

    所以这些都在我的基类中,我从这个类继承来完成我的特定于项目的工作。但现在,这一点被大大简化,就像下面的例子:

    public DataTable GetStages(int id)
    {
        SqlCommand cmd = GetNewCmd("dbo.GetStages");
        cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
        return GetTable(cmd);
    }
    
    public void DeleteStage(int id)
    {
        SqlCommand cmd = GetNewCmd("dbo.DeleteStage");
        cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
        ExecuteNonQuery(cmd);
    }
    

    作为附带的好处,我可以基于存储过程编写此代码的脚本。 Here is the code to do that. 所以它节省了我大量的输入,特别是当有很多参数的时候。

    最后,使用其他面向对象技术,我将代码分为以下几部分:

    GridView1.DataSource = cApp.DB.GetStages(id);
    GridView1.DataBind();
    

    (大多数情况下,中间都有一个业务对象,但您会得到这个想法。) 所有连接字符串、异常日志记录等都封装在这一行中。

    另一个好处是,如果您每次都在复制代码,那么您的基类就可以比以前更多地参与其中。例如,我们将异常记录到数据库表中。只有当失败时,才会将其记录到文本文件中。如果它位于基类中的一个位置,那么这个广泛的逻辑是可以的,但是它不是您想要在整个项目中复制和粘贴的东西。

    这也使得合并一些最佳实践变得容易,例如尽可能晚地打开连接并尽快关闭连接。

        5
  •  1
  •   Dan McClain    15 年前
    SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
    newCommand.CommandType = CommandType.StoredProcedure;
    

    这将无法正常工作,因为您没有使用存储过程,所以应该这样调用上面的命令

    SqlCommand newCommand = new SqlCommand("SELECT * FROM PMInfo");
    newCommand.CommandType = CommandType.Text;
    

    如果要调用存储过程,请按如下方式调用它:

    SqlCommand newCommand = new SqlCommand("spYourProcedure");
    newCommand.CommandType = CommandType.StoredProcedure;
    

    here 在msdn中,有关详细信息,它还将使用参数

        6
  •  1
  •   Henk Holterman    15 年前

    与使用查询只有几个不同之处:

       SqlDataAdapter myAdapter = new SqlDataAdapter(); 
       myAdater.Connection = myConnection;
    
       SqlCommand newCommand = new SqlCommand("spPminfoList");
       newCommand.CommandType = CommandType.StoredProcedure;
       myAdapter.SelectCommand = newCommand;
    

    当然,您必须在数据库中创建SPPMInfoList。

        7
  •  1
  •   user4340666    7 年前

    存储过程示例:

        CREATE PROCEDURE dbo.AddEmp
        @code varchar(10),
        @name varchar(10),
        @address varchar(10)
    AS
        INSERT INTO Employee (Code,NameEmp,Address)
        VALUES (@code,@name,@address)
        RETURN
    

    C代码:

        private void AddButton_Click(object sender, EventArgs e)
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("AddEmp", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@code", SqlDbType.VarChar).Value = textBox1.Text.Trim();
            cmd.Parameters.AddWithValue("@name", SqlDbType.VarChar).Value = textBox2.Text.Trim();
            cmd.Parameters.AddWithValue("@address", SqlDbType.VarChar).Value = textBox3.Text.Trim();
            cmd.ExecuteNonQuery();
            MessageBox.Show("Employee added");
            con.Close();
        }
    

    有关更多说明,请参阅本教程 Using Stored Procedure with C# for beginners

        8
  •  0
  •   MusiGenesis    15 年前

    这不完全是您问题的答案,但在您的情况下,我不会费心将您的查询转换为存储过程,因为这可能是许多额外的工作,没有真正的好处。在过去的几天里,SQL Server中的存储过程比所谓的即席SQL查询更快,因为SQL Server可以计算和缓存查询的执行计划。但是,在现代版本的SQL Server中,数据库在运行一次之后,会缓存每个查询的执行计划,因此,在执行临时查询之后,它的执行速度将与存储过程一样快。

    此外,将查询保存在应用程序代码中的一个真正的和主要的优势是,查询将受源代码管理和可版本控制(当然,假设您使用的是源代码管理)。可以在SQL Server中对存储过程进行版本转换,但这是一项更多的工作,很少有人这样做。

    最后,将查询移动到存储过程意味着重写应用程序代码的大部分,因为存储过程的访问方式与临时SQL查询不同。在开始时使用存储过程编写应用程序可能是有意义的,但是在编写应用程序以使用特殊的SQL查询之后,将其转换为使用存储过程的意义就小得多。

        9
  •  0
  •   Jason Kester    15 年前

    对于它的价值而言,您将希望在代码隐藏中简单地包装存储过程,这是远远不够的。要深入了解这一点,请阅读本文:

    Code on the Road: ExampleCode != ProductionCode

    即席SQL是最简单的修复方法之一,也是我们作为开发人员遇到的最普遍的代码复制形式之一。即使只是思考如何组织数据库交互的几分钟,也会以可维护性和开发速度的形式得到回报。

        10
  •  -1
  •   maheshrao    7 年前

    公共类客户数据访问 { 静态字符串connectionString=configurationmanager.connectionStrings[“testdb”].toString(); 公共列表getCustomerListByName(字符串customerName) { list customerList=new list();