插入错误:列名或提供的值数与表定义不匹配。使用storedprocedure

时间:2014-03-21 13:27:35

标签: c# sql-server-2008 stored-procedures

我收到了以下错误:

  

插入错误:列名或提供的值数不匹配   表定义。

excel中的总列数= 17 表中的总字段= 17 + 3 = 20 3个fiedls中有1个(primarykeyid-autogenerate)2个(将来自另一个文本框),3个是(defaulvalue 1)

我不知道如何将文本框值和默认值传递给过程。

请建议我一个方法

这是我的存储过程代码

USE [Demo]
GO
/****** Object:  StoredProcedure [dbo].[spx_ImportFromExcel07]    Script Date: 03/21/2014 18:25:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[spx_ImportFromExcel07]
   @SheetName varchar(20),
   @FilePath varchar(300),
   @HDR varchar(3),
   @TableName varchar(50)
AS
BEGIN
    DECLARE @SQL nvarchar(1000)
    IF OBJECT_ID (@TableName,'U') IS NOT NULL

      SET @SQL = 'INSERT INTO ' + @TableName + ' SELECT * FROM OPENDATASOURCE'

    ELSE

      SET @SQL = 'SELECT * INTO ' + @TableName + ' FROM OPENDATASOURCE'


    SET @SQL = @SQL + '(''Microsoft.ACE.OLEDB.12.0'',''Data Source='
    SET @SQL = @SQL + @FilePath + ';Extended Properties=''''Excel 12.0;HDR='
    SET @SQL = @SQL + @HDR + ''''''')...['
    SET @SQL = @SQL + @SheetName + ']'
    EXEC sp_executesql @SQL

END

这是我的插入代码:

protected void btnSave_Click(object sender, EventArgs e)
        {
            string FileName = lblFileName.Text;
            string Extension = Path.GetExtension(FileName);
            string FolderPath = Server.MapPath(ConfigurationManager.AppSettings["FolderPath"]);
            string CommandText = "";
            switch (Extension)
            {
                case ".xls": //Excel 97-03
                    CommandText = "spx_ImportFromExcel03";
                    break;
                case ".xlsx": //Excel 07
                    CommandText = "spx_ImportFromExcel07";
                    break;
            }
            //insertDB();
            String strConnString = ConfigurationManager.ConnectionStrings["CARGONETConnectionString"].ConnectionString;
            SqlConnection con = new SqlConnection(strConnString);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = CommandText;
            cmd.Parameters.Add("@SheetName", SqlDbType.VarChar).Value = ddlSheets.SelectedItem.Text;
            cmd.Parameters.Add("@FilePath", SqlDbType.VarChar).Value = FolderPath + FileName;
            cmd.Parameters.Add("@HDR", SqlDbType.VarChar).Value = rbHDR.SelectedItem.Text;
            cmd.Parameters.Add("@TableName", SqlDbType.VarChar).Value = "TB_TransAgentSeaFreightRate";
            cmd.Connection = con;
            try
            {
                con.Open();
                object count = cmd.ExecuteNonQuery();
                lblMessage.ForeColor = System.Drawing.Color.Green;
                lblMessage.Text = count.ToString() + " records inserted.";
            }

            catch (Exception ex)
            {

                lblMessage.ForeColor = System.Drawing.Color.White;
                lblMessage.Text = ex.Message;

            }

            finally
            {

                con.Close();
                con.Dispose();
                Panel1.Visible = true;
                //Panel2.Visible = false;
                dg_AgentSFR.Visible = true;
            }

        }

请帮助我..

我不知道如何将文本框值和默认值传递给storedprocedure。

提前致谢

1 个答案:

答案 0 :(得分:0)

首先,我建议您删除存储过程中的动态SQL。动态SQL会让您容易受到SQL注入攻击。 " lblFileName.Text"是我在提供的代码中看到的最有可能发生注入的地方,但是通过编写存储过程的方式,每个参数都容易受到攻击。在调用存储过程之前,应该将值解析为正确的类型。存储过程中的参数应分别是表中列的类型。至于你正在制作的桌子选择,问问自己这种情况会发生多大变化?

如果由于大量表而为每个表写入插入是不切实际的,那么您需要检查存储过程的SQL注入参数。

如果您需要默认值,则可以轻松地将其放在存储过程中。然后你可以检查并跳过后面代码中的参数。

存储过程:

CREATE PROCEDURE spExample
   @nExample int = 1
AS 

代码背后:

int value
if(int.TryParse(TextBox1.Text, out value))
{
  // add parameter here.
}

http://technet.microsoft.com/en-us/library/ms189330(v=sql.105).aspx

http://en.wikipedia.org/wiki/SQL_injection