如何在 C# 程序中执行存储过程
Posted
技术标签:
【中文标题】如何在 C# 程序中执行存储过程【英文标题】:How to execute a stored procedure within C# program 【发布时间】:2009-08-11 15:04:26 【问题描述】:我想从 C# 程序中执行这个存储过程。
我在 SqlServer 查询窗口中编写了以下存储过程并将其保存为 存储1:
use master
go
create procedure dbo.test as
DECLARE @command as varchar(1000), @i int
SET @i = 0
WHILE @i < 5
BEGIN
Print 'I VALUE ' +CONVERT(varchar(20),@i)
EXEC(@command)
SET @i = @i + 1
END
已编辑:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AutomationApp
class Program
public void RunStoredProc()
SqlConnection conn = null;
SqlDataReader rdr = null;
Console.WriteLine("\nTop 10 Most Expensive Products:\n");
try
conn = new SqlConnection("Server=(local);DataBase=master;Integrated Security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("dbo.test", conn);
cmd.CommandType = CommandType.StoredProcedure;
rdr = cmd.ExecuteReader();
/*while (rdr.Read())
Console.WriteLine(
"Product: 0,-25 Price: $1,6:####.00",
rdr["TenMostExpensiveProducts"],
rdr["UnitPrice"]);
*/
finally
if (conn != null)
conn.Close();
if (rdr != null)
rdr.Close();
static void Main(string[] args)
Console.WriteLine("Hello World");
Program p= new Program();
p.RunStoredProc();
Console.Read();
这会显示异常Cannot find the stored procedure dbo.test
。我需要提供路径吗?如果是,存储过程应该存储在哪个位置?
【问题讨论】:
您最好使用除 master 以外的数据库进行测试。这是一个系统数据库,你最终会导致问题。在 SQL 2012 中,它不会让我在那里创建表。相反,它将允许我创建一个存储过程。 :// 尽管有答案:您是否检查过您的 sp 是否实际上是使用您提供的名称创建的 (dbo.test)?我不知道如果非 dbo 用户尝试创建 dbo.test 会发生什么......它会被创建为 non-dbo.test 吗? @obayhan 这个问题是在您声称可能重复的问题之前 2 年提出的。请在以后将最近的问题标记为重复问题。 【参考方案1】:using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand("ProcedureName", conn)
CommandType = CommandType.StoredProcedure )
conn.Open();
command.ExecuteNonQuery();
【讨论】:
你甚至可以摆脱conn.Close
,暗示Dispose
这种情况确实如此。我喜欢匹配 Open
和 Close
电话。如果您说,将来将连接对象重构为字段并删除 using 语句,您可能会不小心忘记添加 Close
并最终得到一个打开的连接。
如果存储过程需要参数,你会怎么做?只需将参数添加到具有相同名称和类型的命令对象中?
@Dani 是的。只需将参数添加到SqlCommand
对象的Parameters
集合即可。【参考方案2】:
using (SqlConnection conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI"))
conn.Open();
// 1. create a command object identifying the stored procedure
SqlCommand cmd = new SqlCommand("CustOrderHist", conn);
// 2. set the command object so it knows to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which will be passed to the stored procedure
cmd.Parameters.Add(new SqlParameter("@CustomerID", custId));
// execute the command
using (SqlDataReader rdr = cmd.ExecuteReader())
// iterate through results, printing each to console
while (rdr.Read())
Console.WriteLine("Product: 0,-35 Total: 1,2",rdr["ProductName"],rdr["Total"]);
您可以阅读以下一些有趣的链接:
http://www.csharp-station.com/Tutorials/AdoDotNet/Lesson07.aspx http://www.c-sharpcorner.com/UploadFile/dclark/InsOutsinCS11302005072332AM/InsOutsinCS.aspx http://www.codeproject.com/KB/cs/simplecodeasp.aspx http://msdn.microsoft.com/en-us/library/ms171921(VS.80).aspx【讨论】:
你真的应该使用“使用”关键字。将打开/关闭职责推送到框架。 SqlCommand 的定义:public sealed class SqlCommand : System.Data.Common.DbCommand, ICloneable, IDisposable
。将其放入using
语句将有助于清理。【参考方案3】:
在 C# 中调用存储过程:
SqlCommand cmd = new SqlCommand("StoredProcedureName",con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@value",txtValue.Text);
con.Open();
int rowAffected = cmd.ExecuteNonQuery();
con.Close();
【讨论】:
【参考方案4】:using (SqlConnection sqlConnection1 = new SqlConnection("Your Connection String"))
using (SqlCommand cmd = new SqlCommand())
Int32 rowsAffected;
cmd.CommandText = "StoredProcedureName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
rowsAffected = cmd.ExecuteNonQuery();
【讨论】:
我担心 cmd.CommandText = "Stored1" 如何解释我的存储过程。我不知道。 必须将“CommandText”设置为存储过程的名称,然后从 C# 执行,就像您在 SSMS 中执行了“exec StoredProcedureName”一样 - 或者您担心什么?跨度> 如何给上述存储过程的存储过程名称你能告诉我吗?? 所以,首先,您必须创建存储过程,对于您拥有的代码,您需要在开头添加:“create procedure dbo.NameOfYourStoredProcedureHere as” @Cute:如果你有这个作为存储过程,你必须有一个名字!在“CREATE PROCEDURE (procedurename)”调用中使用的名称。如果你没有那个,那么你就没有存储过程(而只是一批 T-SQL 语句),那么你就不能使用“CommandType = StoredProcedure”,显然【参考方案5】:这是通过反射执行带参数和不带参数的存储过程的代码。 请注意,对象的属性名称需要与存储过程的参数匹配。
private static string ConnString = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
private SqlConnection Conn = new SqlConnection(ConnString);
public void ExecuteStoredProcedure(string procedureName)
SqlConnection sqlConnObj = new SqlConnection(ConnString);
SqlCommand sqlCmd = new SqlCommand(procedureName, sqlConnObj);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlConnObj.Open();
sqlCmd.ExecuteNonQuery();
sqlConnObj.Close();
public void ExecuteStoredProcedure(string procedureName, object model)
var parameters = GenerateSQLParameters(model);
SqlConnection sqlConnObj = new SqlConnection(ConnString);
SqlCommand sqlCmd = new SqlCommand(procedureName, sqlConnObj);
sqlCmd.CommandType = CommandType.StoredProcedure;
foreach (var param in parameters)
sqlCmd.Parameters.Add(param);
sqlConnObj.Open();
sqlCmd.ExecuteNonQuery();
sqlConnObj.Close();
private List<SqlParameter> GenerateSQLParameters(object model)
var paramList = new List<SqlParameter>();
Type modelType = model.GetType();
var properties = modelType.GetProperties();
foreach (var property in properties)
if (property.GetValue(model) == null)
paramList.Add(new SqlParameter(property.Name, DBNull.Value));
else
paramList.Add(new SqlParameter(property.Name, property.GetValue(model)));
return paramList;
【讨论】:
【参考方案6】:SqlConnection conn = null;
SqlDataReader rdr = null;
conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
conn.Open();
// 1. create a command object identifying
// the stored procedure
SqlCommand cmd = new SqlCommand("CustOrderHist", conn);
// 2. set the command object so it knows
// to execute a stored procedure
cmd.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which
// will be passed to the stored procedure
cmd.Parameters.Add(new SqlParameter("@CustomerID", custId));
// execute the command
rdr = cmd.ExecuteReader();
// iterate through results, printing each to console
while (rdr.Read())
Console.WriteLine("Product: 0,-35 Total: 1,2", rdr["ProductName"], rdr["Total"]);
【讨论】:
【参考方案7】:通过使用 Ado.net
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace PBDataAccess
public class AddContact
// for preparing connection to sql server database
private SqlConnection conn;
// for preparing sql statement or stored procedure that
// we want to execute on database server
private SqlCommand cmd;
// used for storing the result in datatable, basically
// dataset is collection of datatable
private DataSet ds;
// datatable just for storing single table
private DataTable dt;
// data adapter we use it to manage the flow of data
// from sql server to dataset and after fill the data
// inside dataset using fill() method
private SqlDataAdapter da;
// created a method, which will return the dataset
public DataSet GetAllContactType()
// retrieving the connection string from web.config, which will
// tell where our database is located and on which database we want
// to perform opearation, in this case we are working on stored
// procedure so you might have created it somewhere in your database.
// connection string will include the name of the datasource, your
// database name, user name and password.
using (conn = new SqlConnection(ConfigurationManager.ConnectionString["conn"]
.ConnectionString))
// Addcontact is the name of the stored procedure
using (cmd = new SqlCommand("Addcontact", conn))
cmd.CommandType = CommandType.StoredProcedure;
// here we are passing the parameters that
// Addcontact stored procedure expect.
cmd.Parameters.Add("@CommandType",
SqlDbType.VarChar, 50).Value = "GetAllContactType";
// here created the instance of SqlDataAdapter
// class and passed cmd object in it
da = new SqlDataAdapter(cmd);
// created the dataset object
ds = new DataSet();
// fill the dataset and your result will be
stored in dataset
da.Fill(ds);
return ds;
****** Stored Procedure ******
CREATE PROCEDURE Addcontact
@CommandType VARCHAR(MAX) = NULL
AS
BEGIN
IF (@CommandType = 'GetAllContactType')
BEGIN
SELECT * FROM Contacts
END
END
【讨论】:
您的评论行坏了,如果您可以在评论中提供对我们有好处的存储过程。 已经在代码中添加了存储过程,看看吧。【参考方案8】:这是一个存储过程的示例,它返回一个值并在 c# 中执行
CREATE PROCEDURE [dbo].[InsertPerson]
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),@LastName nvarchar(50),
@PersonID int output
AS
BEGIN
insert [dbo].[Person](LastName,FirstName) Values(@LastName,@FirstName)
set @PersonID=SCOPE_IDENTITY()
END
Go
--------------
// Using stored procedure in adapter to insert new rows and update the identity value.
static void InsertPersonInAdapter(String connectionString, String firstName, String lastName)
String commandText = "dbo.InsertPerson";
using (SqlConnection conn = new SqlConnection(connectionString))
SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].[Person]", conn);
mySchool.InsertCommand = new SqlCommand(commandText, conn);
mySchool.InsertCommand.CommandType = CommandType.StoredProcedure;
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));
SqlParameter personId = mySchool.InsertCommand.Parameters.Add(new SqlParameter("@PersonID", SqlDbType.Int, 0, "PersonID"));
personId.Direction = ParameterDirection.Output;
DataTable persons = new DataTable();
mySchool.Fill(persons);
DataRow newPerson = persons.NewRow();
newPerson["FirstName"] = firstName;
newPerson["LastName"] = lastName;
persons.Rows.Add(newPerson);
mySchool.Update(persons);
Console.WriteLine("Show all persons:");
ShowDataTable(persons, 14);
【讨论】:
【参考方案9】:使用 Dapper。所以我添加了这个,希望有人帮助。
public void Insert(ProductName obj)
SqlConnection connection = new SqlConnection(Connection.GetConnectionString());
connection.Open();
connection.Execute("ProductName_sp", new
@Name = obj.Name, @Code = obj.Code, @CategoryId = obj.CategoryId, @CompanyId = obj.CompanyId, @ReorderLebel = obj.ReorderLebel, @logo = obj.logo,@Status=obj.Status, @ProductPrice = obj.ProductPrice,
@SellingPrice = obj.SellingPrice, @VatPercent = obj.VatPercent, @Description=obj.Description, @ColourId = obj.ColourId, @SizeId = obj.SizeId,
@BrandId = obj.BrandId, @DisCountPercent = obj.DisCountPercent, @CreateById =obj.CreateById, @StatementType = "Create" , commandType: CommandType.StoredProcedure);
connection.Close();
【讨论】:
最好在连接声明前使用using
,或者将Close放在finally
块中。否则,如果发生异常,连接永远不会关闭。【参考方案10】:
没有Dapper 在这里回答。所以我加了一个
using Dapper;
using System.Data.SqlClient;
using (var cn = new SqlConnection(@"Server=(local);DataBase=master;Integrated Security=SSPI"))
cn.Execute("dbo.test", commandType: CommandType.StoredProcedure);
【讨论】:
【参考方案11】:请查看 Crane(我是作者)
https://www.nuget.org/packages/Crane/
SqlServerAccess sqlAccess = new SqlServerAccess("your connection string");
var result = sqlAccess.Command().ExecuteNonQuery("StoredProcedureName");
还有许多您可能喜欢的其他功能。
【讨论】:
如何使用 Crane 返回多个数据集?我的存储过程返回 3 个数据集,我只对第二个数据集感兴趣。但是 Crane 只给我回了第一个。【参考方案12】:您的意思是您的代码是 DDL? 如果是这样,MSSQL 没有区别。上面的例子很好地展示了如何调用它。只要确保
CommandType = CommandType.Text
【讨论】:
【参考方案13】:最简单直接的..
SqlCommand cmd = new SqlCommand("StoredProcedureName",con); // Just like you declared it
cmd.CommandType = CommandType.StoredProcedure; // an attribute related to the object
cmd.Parameters.AddWithValue("@value",txtValue.Text); // Parameter name and text source
con.Open();
int rowAffected = cmd.ExecuteNonQuery();
con.Close();
【讨论】:
【参考方案14】:我所做的,就我而言,我想在 dataGridView 中显示过程的结果:
using (var command = new SqlCommand("ProcedureNameHere", connection)
// Set command type and add Parameters
CommandType = CommandType.StoredProcedure,
Parameters = new SqlParameter("@parameterName",parameterValue)
)
// Execute command in Adapter and store to dataset
var adapter = new SqlDataAdapter(command);
var dataset = new DataSet();
adapter.Fill(dataset);
// Display results in DatagridView
dataGridView1.DataSource = dataset.Tables[0];
【讨论】:
以上是关于如何在 C# 程序中执行存储过程的主要内容,如果未能解决你的问题,请参考以下文章