我正在尝试INSERT
将我的数据分为两个表Services
和Service-line
解释我的存储过程:
如果未找到,则会在Services
表格中创建表格中信息的新记录,然后使用scope_identity
获取ID,并使用ID
表示Service-Line
1}}表。
此外,ID还会返回到表单并保留为tre。
稍后在Service-Line
中插入第二条记录时,存储过程会检查现有的ID
;如果找到,则此时,它需要表单中的ID
并在Service-Line
这是我的存储过程
请耐心等待我,因为我正在使用此代码和测试,很多行都被注释掉了
ALTER PROCEDURE [dbo].[InsertServiceServiceLine] (
--Services Entry
--FOR IF CONDITION ---CHECK THE DEFAULT VALUE IN THE FORM on SID
@ExistingSID int,
--SEELCT PARAMETES DEF VALUES
@ComboBoxSelectedBike varchar(100),
-- INPUT PARAMETERES FOR NEW RECORD
@CID int,
@Status bit = 1,
@CurrentMeter int,
@Labor decimal(20,0),
@GrandTotal decimal(20,0) = ISNULL,
--@NextService datetime,
--Service Line
@Spare nvarchar(500),
@Quantity int,
@Uprice decimal(20,2),
@Subtotal decimal(20,2)
)
AS
BEGIN
IF (@ExistingSID <= 0)
BEGIN
SET NOCOUNT ON;
DECLARE @BikeID int
SELECT @BikeID = (SELECT BikeID FROM TblBikeNames WHERE BikeName = @ComboBoxSelectedBike)
INSERT INTO [AutoDB_Sample].[dbo].[TblServices]
(CID,BikeID,Status,CurrentMeter,Labor,DateOfService)
VALUES
(@CID,@BikeID,@Status,@CurrentMeter,@Labor,GETDATE())
DECLARE @SID int
SET @SID = SCOPE_IDENTITY()
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(@SID,@Spare,@Quantity,@Uprice,@Subtotal,GETDATE())
RETURN @SID
END
ELSE
BEGIN
INSERT INTO [AutoDB_Sample].[dbo].[TblServiceLine]
(SID,Spare,Quantity,Uprice,Subtotal,DateCreated)
VALUES
(@ExistingSID,@Spare,@Quantity,@Uprice,@Subtotal,GETDATE())
END
END
当我在C#Windows窗体
中使用此存储过程时,它给出了一个错误过程或函数包含太多参数
这是错误的屏幕截图
我认为将我的登录信息放入SP会很棒并且可以提高我的应用程序的性能。但现在卡住了。
这是我的C#代码
public void AddItemIntoServices_ServiceLine()
{
ConnectionStringSettings consetting = ConfigurationManager.ConnectionStrings["AutoDB"];
String ConnectionString = consetting.ConnectionString;
SqlConnection con = new SqlConnection(ConnectionString);
try
{
con.Open(); // open the connection
// Specify the name of the Stored Procedure you will call
String SP_Name = "InsertServiceServiceLine";
// Create the SQL Command object and specify that this is a SP.
SqlCommand cmd = new SqlCommand(SP_Name, con);
cmd.CommandType = CommandType.StoredProcedure;
// Specify values for the input parameters of our Stored Procedure
// Parameters MUST be named the same as the parameters defined in the Stored Procedure.
//~~ If Condition Parameter ****************************************************************************~~//
int exitstingSID;
if (int.TryParse(LblSID_Data.Text, out exitstingSID)) ;
SqlParameter ExistingSID = new SqlParameter("@ExistingSID", exitstingSID);
ExistingSID.Direction = ParameterDirection.Input;
ExistingSID.DbType = DbType.Int16;
cmd.Parameters.Add(ExistingSID);
//Parameter to select Bike ID from Selected Bike Name
SqlParameter ParamBikeID = new SqlParameter("@ComboBoxSelectedBike", ComboBx_BikeNames.Text);
ParamBikeID.Direction = ParameterDirection.Input;
ParamBikeID.DbType = DbType.String;
cmd.Parameters.Add(ParamBikeID);
//~~ Customer Info ************************************************************************************~~//
//CID Convertion
int P_CID;
if (int.TryParse(LblCID_Data.Text, out P_CID)) ;
cmd.Parameters.AddWithValue("@CID", P_CID);
cmd.Parameters.AddWithValue("@Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("@Vnum", this.TxtBx_VehicleNumber.Text);
//~~ Service Info ************************************************************************************~~//
//Labor Convertion
int Laborint;
if (int.TryParse(TxtBxLabor.Text, out Laborint)) ;
SqlParameter ParamLabor = new SqlParameter("@Labor", Laborint);
ParamLabor.Direction = ParameterDirection.Input;
ParamLabor.DbType = DbType.Int16;
cmd.Parameters.Add(ParamLabor);
//CurrentMeterConversion
int currentMeterint;
if (int.TryParse(TxtBx_CurrentMeter.Text, out currentMeterint)) ;
SqlParameter ParamCurrentMeter = new SqlParameter("@CurrentMeter", currentMeterint);
ParamCurrentMeter.Direction = ParameterDirection.Input;
ParamCurrentMeter.DbType = DbType.Int16;
cmd.Parameters.Add(ParamCurrentMeter);
//Return Value
SqlParameter ParamReturn = new SqlParameter("@SID", SqlDbType.Int);
ParamReturn.Direction = ParameterDirection.Output;
ParamReturn.DbType = DbType.Int16;
cmd.Parameters.Add(ParamReturn);
//~~ Service Info ************************************************************************************~~//
//Converstions
Decimal UP, ST;
if (Decimal.TryParse(TxtBx_UnitPrice.Text, out UP)) ;
if (Decimal.TryParse(TxtBxTotal.Text, out ST)) ;
//SpareName
cmd.Parameters.AddWithValue("@Spare", ComboBx_SparesName.Text);
//Quantity
cmd.Parameters.AddWithValue("@Qty", NumericBx_Quantity.Value);
//Unit Price
SqlParameter ParamUp = new SqlParameter("@Uprice", UP);
ParamUp.Direction = ParameterDirection.Input;
ParamUp.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamUp);
//Total
SqlParameter ParamTot = new SqlParameter("Subtotal", ST);
ParamTot.Direction = ParameterDirection.Input;
ParamTot.DbType = DbType.Decimal;
cmd.Parameters.Add(ParamTot);
cmd.ExecuteNonQuery();
String _returnedSID = cmd.Parameters["@SID"].Value.ToString();
LblSID_Data.Text = _returnedSID;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
con.Close();
clear();
ToolStripLable_Status.Text = "New Service Record Created";
}
}
答案 0 :(得分:1)
存储过程定义中有12个参数(如果我计算正确),但是,您的代码可能有多于或少于此值。代码中定义了太多参数,或者存储过程需要第13个参数。我认为这个错误提到了前者,但我有时会让他们感到困惑。
无论如何,错误总是由于参数数量不匹配造成的,并确保方向(输入/输出)设置正确,并且输入的所有内容都正常。
答案 1 :(得分:1)
通过命令集合传递的参数列表应该与存储过程的名称,类型和方向完全匹配。
命令集中包含的参数列表与存储过程所需的参数不匹配,因此您会收到错误。
乍一看,我可以说:cmd.Parameters.AddWithValue("@Cname", this.TxtBx_CustomerName.Text);
cmd.Parameters.AddWithValue("@Vnum", this.TxtBx_VehicleNumber.Text);
SqlParameter ParamReturn = new SqlParameter("@SID", SqlDbType.Int);
是添加到命令集合的参数,但不存在于存储过程参数列表中。
相反,我们有存储过程所需的参数@status bit
和@GrandTotal decimal(20,0) = ISNULL,
但不在列表中。 (顺便说一下,NULL参数的默认语法是@GrandTotal decimal(20,0) = NULL
最后,存储过程命名参数@Quantity
,但您添加了一个名为@Qty
的参数。
现在还存在应该匹配的参数类型的问题,否则您最多会冒自动转换的风险或者说明类型不匹配的错误消息。
你有很多int类型的参数,但你传递Int16类型的参数,而正确的类型是Int32。并且参数@Labor
的类型中存在更明显的错误,预计sp将是小数,但是将其添加为整数(16)