如何使用 ado.net 调用存储过程
Posted
技术标签:
【中文标题】如何使用 ado.net 调用存储过程【英文标题】:How to call a stored procedure using ado.net 【发布时间】:2021-12-29 12:30:14 【问题描述】:private void button1_Click(object sender, EventArgs e)
try
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Data Source=*******;Initial Catalog=ChatApp;User ID=Chatapplication;Password=****";
conn.Open();
SqlCommand cmd = new SqlCommand();
string chatroomidno = textBox1.Text;
string chatroomname = textBox2.Text;
//cmd.CommandText = "Select ChatRoomID=@ChatRoomID,ChatRoomName=@ChatRoomName from tblChatRoom";
//cmd.Connection = conn;
SqlDataAdapter adapt = new SqlDataAdapter("Chatroomapp",conn);
adapt.SelectCommand.CommandType = CommandType.StoredProcedure;
DataSet ds=new DataSet();
DataTable dt = new DataTable();
adapt.SelectCommand.Parameters.Add(new SqlParameter("@ChatRoomID", SqlDbType.VarChar, 100));
adapt.SelectCommand.Parameters["@ChatRoomID"].Value = chatroomidno;
adapt.SelectCommand.Parameters.Add(new SqlParameter("@ChatRoomName", SqlDbType.VarChar, 50));
adapt.SelectCommand.Parameters["@ChatRoomName"].Value = chatroomname;
adapt.Fill(ds, "tblChatRoom");
if (dt.Rows.Count > 0)
MessageBox.Show("Connection Succedded");
else
MessageBox.Show("Connection Fails");
catch (Exception ex)
MessageBox.Show("Error", ex.Message);
在编译程序时,我在数据库中只收到连接失败消息框。我发现正确,如何克服程序以获取连接成功消息框。
【问题讨论】:
【参考方案1】:好吧,您正在填充 ds
数据集 - 但随后您正在检查 dt
数据表中是否存在行...当然,这永远不会起作用!
如果您只需要一个 DataTable
- 只需单独使用和填写该数据表 - 不需要 DataSet
的开销。另外,将您的 SqlConnection
和 SqlCommand
放入 using 块中,如下所示:
using (SqlConnection conn = new SqlConnection("Data Source=*******;Initial Catalog=ChatApp;User ID=Chatapplication;Password=****"))
using (SqlCommand cmd = new SqlCommand("Chatroomapp", conn))
string chatroomidno = textBox1.Text;
string chatroomname = textBox2.Text;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
adapt.SelectCommand.CommandType = CommandType.StoredProcedure;
adapt.SelectCommand.Parameters.Add(new SqlParameter("@ChatRoomID", SqlDbType.VarChar, 100));
adapt.SelectCommand.Parameters["@ChatRoomID"].Value = chatroomidno;
adapt.SelectCommand.Parameters.Add(new SqlParameter("@ChatRoomName", SqlDbType.VarChar, 50));
adapt.SelectCommand.Parameters["@ChatRoomName"].Value = chatroomname;
// fill the data table - no need to explicitly call `conn.Open()` -
// the SqlDataAdapter automatically does this (and closes the connection, too)
DataTable dt = new DataTable();
adapt.Fill(dt);
if (dt.Rows.Count > 0)
MessageBox.Show("Connection Succedded");
else
MessageBox.Show("Connection Fails");
仅仅因为您在dt.Rows
中没有返回任何行并不一定意味着您的连接失败......可能只是没有符合您的搜索条件的行!连接工作得很好——但 SQL 命令没有返回任何行。
【讨论】:
非常感谢您的解释!大约 2 天以来,我一直在努力使用我不熟悉的方法连接到我的数据库,这终于让我到了那里。很有帮助!【参考方案2】:连接失败意味着您的程序和数据库之间出现了问题。没有返回记录并不意味着连接失败。这只是意味着您的表是空的 - 它不包含任何记录。
使用ADO.NET
和stored procedures
会与您所做的有所不同。如果您需要检查连接是否失败,最好检查catch
部分中返回的异常类型。
以下是我将如何做到的。我会创建一个单独的方法来处理我的调用,然后在你的button1_Click
中我会调用这个方法:
public async Task<ChatRoom> GetAsync(string chatRoomId, string chatRoomName)
try
string connectionString = ConfigurationManager.ConnectionStrings["Db"].ConnectionString;
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
await sqlConnection.OpenAsync();
using (SqlCommand sqlCommand = new SqlCommand("ChatRooms_Get", sqlConnection))
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.Add(new SqlParameter("@ChatRoomID", chatRoomId));
sqlCommand.Parameters.Add(new SqlParameter("@ChatRoomName", chatRoomName));
using (SqlDataReader sqlDataReader = await sqlCommand.ExecuteReaderAsync())
ChatRoom chatRoom = null;
if (await sqlDataReader.ReadAsync())
chatRoom = new ChatRoom();
chatRoom.Id = sqlDataReader.GetFieldValue<string>(0);
chatRoom.Name = sqlDataReader.GetFieldValue<string>(1);
chatRooms.Add(chatRoom);
return chatRoom;
catch (Exception exception)
// Try checking if the connection failed here
throw exception;
我的聊天室domain model
可能看起来像这样:
public class ChatRoom
public string Id get; set;
public string Name get; set;
存储过程应该是这样的:
CREATE PROCEDURE [dbo].[ChatRooms_Get]
(
@ChatRoomID VARCHAR(100),
@ChatRoomName VARCHAR(50)
)
AS
BEGIN
SET NOCOUNT ON;
SELECT
ChatRoomID,
ChatRoomName
FROM
tblChatRoom
WHERE
ChatRoomID = @ChatRoomID
AND ChatRoomName = @ChatRoomName;
END
GO
然后在调用方法中,您将获得聊天室并使用它做任何您需要做的事情。对于这个例子,我只是检查了它是否存在:
try
ChatRoom chatRoom = await chatRoomRepository.GetAsync(chatRoomId, chatRoomName);
if (chatRoom != null)
MessageBox.Show("Record found");
else
MessageBox.Show("No record found");
catch (Exception exception)
throw exception;
我希望这会有所帮助。
【讨论】:
以上是关于如何使用 ado.net 调用存储过程的主要内容,如果未能解决你的问题,请参考以下文章
使用 ADO.NET 获取 Oracle 包中过程的存储过程元数据
ADO.NET 调用 T-SQL 存储过程会导致 SqlTimeoutException
通过 ADO.Net 命令调用 Informix 存储过程的最佳/正确方法?
在 ASP.Net Core 项目中使用 ADO.Net 将 JSON 类型作为参数传递给 SQL Server 2016 存储过程