在C#中执行更新存储过程
本文关键字:更新 存储过程 执行 | 更新日期: 2023-09-27 18:27:38
我需要知道我是否正确地编写了存储过程,以及用于执行的C#代码是否正确。由于某种原因,返回的错误是"c16b"附近的语法不正确。旧错误
现在的新错误是:过程或函数"sptimeupdate"需要参数"@date",但未提供该参数。
ClientID列中用于验证和更新的nvarchar字符串是3fc8ffa1-c16b-4d7b-9e55-e88dfe15277,但粗体部分仅显示在错误处理的调试测试intel意义上
ALTER PROCEDURE sptimeupdate
@id nvarchar(50),
@date datetime
AS
BEGIN
SET NOCOUNT ON;
UPDATE ClientTable
SET Today_Date=(@date)
WHERE ClientID=(@id)
END
//--------------above stored procedure--------------------------------
//--------------Executing the stored procedure in C#
IEnumerable<XElement> searchClientID =
from clientid in main.XPathSelectElements("Network/ClientID")
where (string)clientid.Attribute("id") == IntializedPorts[i].ToString()
select clientid;
foreach (string clientid in searchClientID)
{
for (int up = 0; up < IntializedPorts.Count(); up++)
{
//Update the current time in the clientid tble.
//Renames the table copy for groups
try
{
string[] Clientid; //client id array
Clientid = new string[IntializedPorts.Count()]; //Intialization of the array
Clientid[up] = clientid.ToString();
DateTime td = Convert.ToDateTime(toolDate.Text); //Just added a datetime object withdate
SqlConnection sqlConnectionCmdString = new SqlConnection(@"Data=.'SQLEXPRESS;AttachDbFilename=C:'Users'Shawn'Documents'Visual Studio 2010'Projects'Server'database'ClientRegit.mdf;Integrated Security=True;User Instance=True");
//EXECUTE THE STORED PROCEDURE sptimedate
// string UpdateCommand = "sptimeupdate" + Clientid[up].ToString() + toolDate.Text;
string UpdateCommand = "sptimeupdate" + "'" + Clientid[up].ToString() + "'" + "'" +td.ToString()+ "'"; //this is the new UpdateCommand string as to pass parameters to stored procedure
SqlCommand sqlRenameCommand = new SqlCommand(UpdateCommand, sqlConnectionCmdString);
sqlConnectionCmdString.Open();
sqlRenameCommand.ExecuteNonQuery();
sqlConnectionCmdString.Close();
}
catch(DataException ex)
{ MessageBox.Show("Failed to UpdateCurrentTime","DataError",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
}
当您从代码中调用存储过程时,您需要创建一个命令,其命令类型设置为StoredProcedure,否则引擎会尝试使用命令文本,因为它是SELECT INSERT等sql文本。但最重要的是,您需要在命令的parameters集合中传递存储过程所需的参数
因此,这可能是取代实际的代码
string UpdateCommand = "sptimeupdate";
using(SqlConnection sqlConnectionCmdString = new SqlConnection(......))
using(SqlCommand sqlRenameCommand = new SqlCommand(UpdateCommand, sqlConnectionCmdString))
{
DateTime td = Convert.ToDateTime(toolDate.Text);
sqlRenameCommand.CommandType = CommandType.StoredProcedure;
sqlRenameCommand.Parameters.Add("@id", SqlDbType.NVarChar).Value = Clientid[up].ToString();
sqlRenameCommand.Parameters.Add("@date", SqlDbType.DateTime).Value = td;
sqlConnectionCmdString.Open();
sqlRenameCommand.ExecuteNonQuery();
}
注意两件事。创建连接时,最好遵循using语句,以确保正确关闭和处理连接。其次,sp期望的DateTime参数应作为DateTime而不是字符串传递。当然,这意味着您应该确保toolDate的内容可以转换为DateTime值。
您的错误源自以下代码行:
string UpdateCommand = "sptimeupdate" + Clientid[up].ToString() + toolDate.Text;
在这里,您只是将Clientid[up].ToString()
作为一个字符串连接到另一个字符串中,与toolDate.Text
相同,都没有和sql标记
您得到的SQL查询如下所示(假设toolDate.Text为"2014-10-23"):
sptimeupdate3fc8ffa1-c16b-4d7b-9e55-1e88dfe152772014-10-23
正如您所看到的,这不是一个正确的SQL命令。
在调用简单的SQL命令时,应始终使用参数化的命令语句
但是在您的情况下,您实际上是在调用一个存储过程。
因此,请更改您的代码,以便像处理存储过程一样处理它,例如下面的示例。
// Create the connection object once
using (SqlConnection sqlConnectionCmdString = new SqlConnection(@"Data=.'SQLEXPRESS;AttachDbFilename=C:'Users'Shawn'Documents'Visual Studio 2010'Projects'Server'database'ClientRegit.mdf;Integrated Security=True;User Instance=True"))
{
// Same with the SqlCommand object and adding the parameters once also
SqlCommand sqlRenameCommand = new SqlCommand("sptimeupdate", sqlConnectionCmdString);
sqlRenameCommand.CommandType = CommandType.StoredProcedure;
sqlRenameCommand.Parameters.Add("@id", SqlDbType.NVarChar);
sqlRenameCommand.Parameters.Add("@datetime", SqlDbType.DateTime);
// Open the connection once only
sqlConnectionCmdString.Open();
foreach (string clientid in searchClientID)
{
for (int up = 0; up < IntializedPorts.Count; up++)
{
try
{
// The below three lines seem redundant.
// Clientid[up] will be equal to clientid after it all, so just use clientid
//string[] Clientid;
//Clientid = new string[IntializedPorts.Count];
//Clientid[up] = clientid.ToString();
sqlRenameCommand.Parameters["@id"].Value = clientid;
sqlRenameCommand.Parameters["@datetime"].Value = toolDate.Text;
sqlRenameCommand.ExecuteNonQuery();
}
// Might want to move this try..catch outside the two loops,
// otherwise you will get this message each time an error happens
// which might be alot, depending on the side of searchClientID
catch (SqlException)
{
MessageBox.Show("Failed to UpdateCurrentTime", "DataError", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
注意:请阅读上面代码中的注释,以获取更多建议和建议。为每次迭代重新创建SqlConnection和SqlCommand将对应用程序的性能产生影响。因此,最好只创建一次,然后重复使用它们,直到完成为止。
可以在这里进行进一步的阅读:
- SqlCommand(页面底部有一些不错的示例)
- SqlCommand的dotnetperls版本
请注意,您的sql过程的代码看起来很好,您可以删除SET NOTCOUNT ON
,因为在这种情况下