将参数值从DataColumn转换为String?

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
这是我要在MS SQL中插入的位置
xxx.jpg

抛出的Visual Studio是"无法将参数值从DataColumn转换为String。"

这是我要插入的代码:
private void MSSQLInsert()
        {
            newProdID = 0;
            
            string ConnStrMSSQL = "Data Source=192.168....;Initial Catalog=xxxx;Persist Security Info=True;User ID=sa;Password=xxxxxx;";
            using (SqlConnection con = new SqlConnection(ConnStrMSSQL)) 
            {
                con.Open();
            
                using (SqlCommand command = new SqlCommand(
                    "INSERT INTO tbRecords VALUES (@sPersonnelCode, @sTerminalCode, " +
                    "@sOperationCode, @sItemCode, @sItemDescription, @nJobOrder, @nMPS, " +
                    "@nRecordType, @nQTY, @dStartTime, @dFinishTime, @sSONumber, @sSONumberItemCode, " +
                    "@dLatestStarting, @dLatestFinishing, @sComputerName, @sDatabase);",
                    con)) 
                {
                    command.Parameters.Add(new SqlParameter("@sPersonnelCode", System.Data.SqlDbType.VarChar, 3));
                    command.Parameters.Add(new SqlParameter("@sTerminalCode", System.Data.SqlDbType.VarChar, 4));
                    command.Parameters.Add(new SqlParameter("@sOperationCode", System.Data.SqlDbType.VarChar, 6));
                    command.Parameters.Add(new SqlParameter("@sItemCode", System.Data.SqlDbType.VarChar, 30));
                    command.Parameters.Add(new SqlParameter("@sItemDescription", System.Data.SqlDbType.VarChar, 70));
                    command.Parameters.Add(new SqlParameter("@nJobOrder", System.Data.SqlDbType.VarChar, 10));
                    command.Parameters.Add(new SqlParameter("@nMPS", System.Data.SqlDbType.VarChar, 5));
                    command.Parameters.Add(new SqlParameter("@nRecordType", System.Data.SqlDbType.Bit));
                    command.Parameters.Add(new SqlParameter("@nQTY", System.Data.SqlDbType.Decimal));
                    command.Parameters.Add(new SqlParameter("@dStartTime", System.Data.SqlDbType.DateTime));
                    command.Parameters.Add(new SqlParameter("@dFinishTime", System.Data.SqlDbType.DateTime));
                    command.Parameters.Add(new SqlParameter("@sSONumber", System.Data.SqlDbType.VarChar, 10));
                    command.Parameters.Add(new SqlParameter("@sSONumberItemCode", System.Data.SqlDbType.VarChar, 20));
                    command.Parameters.Add(new SqlParameter("@dLatestStarting", System.Data.SqlDbType.Date));
                    command.Parameters.Add(new SqlParameter("@dLatestFinishing", System.Data.SqlDbType.Date));
                    command.Parameters.Add(new SqlParameter("@sComputerName", System.Data.SqlDbType.VarChar, 30));
                    command.Parameters.Add(new SqlParameter("@sDatabase", System.Data.SqlDbType.VarChar, 15));
                    command.Parameters["@sPersonnelCode"].Value = strPersonnelCode;
                    command.Parameters["@sTerminalCode"].Value = equalDT.Columns["Tezgah"];
                    command.Parameters["@sOperationCode"].Value = equalDT.Columns["OperationCode"];
                    command.Parameters["@sItemCode"].Value = equalDT.Columns["ItemCode"];
                    command.Parameters["@sItemDescription"].Value = equalDT.Columns["ItemDescription"];
                    command.Parameters["@nJobOrder"].Value = equalDT.Columns["JobOrder"];
                    command.Parameters["@nMPS"].Value = equalDT.Columns["Evrak"];
                    command.Parameters["@nRecordType"].Value = 1;
                    command.Parameters["@nQTY"].Value = 1;
                    command.Parameters["@dStartTime"].Value = dateTimeNow();
                    command.Parameters["@dFinishTime"].Value = dateTimeNow();
                    command.Parameters["@sSONumber"].Value = equalDT.Columns["SONumber"];
                    command.Parameters["@sSONumberItemCode"].Value = equalDT.Columns["SONumberItemCode"];
                    command.Parameters["@dLatestStarting"].Value = equalDT.Columns["LatestStarting"];
                    command.Parameters["@dLatestFinishing"].Value = equalDT.Columns["LatestFinishing"];
                    command.Parameters["@sComputerName"].Value = machineName;
                    command.Parameters["@sDatabase"].Value = getDBname;

                    command.ExecuteNonQuery();

                    // below for seeing colomns in DataTable equalDT
                    //0 takas.Columns.Add(new DataColumn("Tezgah", typeof(string)));
                    //1 takas.Columns.Add(new DataColumn("TezgahAdi", typeof(string)));
                    //2 takas.Columns.Add(new DataColumn("OperationCode", typeof(string)));
                    //3 takas.Columns.Add(new DataColumn("OperationName", typeof(string)));
                    //4 takas.Columns.Add(new DataColumn("ItemCode", typeof(string)));
                    //5 takas.Columns.Add(new DataColumn("ItemDescription", typeof(string)));
                    //6 takas.Columns.Add(new DataColumn("JobOrder", typeof(string)));
                    //7 takas.Columns.Add(new DataColumn("Evrak", typeof(string)));
                    //8 takas.Columns.Add(new DataColumn("QTY", typeof(int)));
                    //9 takas.Columns.Add(new DataColumn("SONumber", typeof(string)));
                    //10 takas.Columns.Add(new DataColumn("SONumberItemCode", typeof(string)));
                    //11 takas.Columns.Add(new DataColumn("LatestStarting", typeof(DateTime)));
                    //12 takas.Columns.Add(new DataColumn("LatestFinishing", typeof(DateTime)));
                }
            }
        }
 

狂暴风暴

知名会员
已加入
2014年8月6日
留言内容
85
地点
南非鲁德普特
编程经验
10+
我不太确定,但是看来您正在尝试在varchar中转储完整的列。例如。像这样的线

C#:
command.Parameters["@sTerminalCode"].Value = equalDT.Columns["Tezgah"];

但是如前所述,不确定是否是问题所在。

附带说明:
使用SA用户访问数据库是一个非常不好的习惯。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
没错!这种方法非常有效。您为什么提供我使用适配器来更改我的代码?在我的方法中,不需要使用适配器吗?您的原因导致我浪费时间更改整个代码。

坦率地说,因为您的代码是垃圾。如果您使用的是DataTable,则将假定您有多行要保存。在那种情况下,您将不得不遍历这些行并为每个行调用ExecuteNonQuery,否则将以正确的方式进行操作,并使用数据适配器一次性保存大量数据。

如果您只有一个记录要保存,那么为什么首先要有一个DataTable?您可以使用一个,但是为什么要使用,除非有您没有告诉我们的某些特定要求?如果您坚持使用DataTable存储单个DataRow,那么您仍然必须从表中获取该行,并使用其字段值填充参数。

除此之外,更改要使用数据适配器的代码不会比使它以任何其他方式(甚至更少)工作所需的精力更多。
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
坦率地说,因为您的代码是垃圾。
可能是这样,但是无论如何它都能工作,我知道是因为我在另一个项目中成功使用了该方法。
如果您使用的是DataTable,则将假定您有多行要保存。
从我的项目的结构中只能检索到一行。
在这种情况下,您将不得不遍历这些行并为每个行调用ExecuteNonQuery,否则将以正确的方式进行操作,并使用数据适配器一次性节省很多。
您绝对正确,但是正如我提到的,它只有一行数据。
如果您只有一个记录要保存,那么为什么首先要有一个DataTable?
因为使用DataTable可以解决复杂性,所以我将两种不同的SQL Server数据与我的方法结合在一起。
如果您坚持使用DataTable存储单个DataRow,那么您仍然必须从表中获取该行,并使用其字段值填充参数。
首先,我无法想到使用DataTable的想法使我变得简单。实际上,即使将DataTable和DataRow放在同一杯水中也是如此。
除此之外,更改要使用数据适配器的代码不会比使它以任何其他方式(甚至更少)工作所需的精力更多。
我在您的文章中看到,DataAdapter在第一次分配时使用了Select查询,为什么?我不需要那个,因为这让我感到困惑,没有想到要使用它。

顺便说一句,这对我的处理来说看起来不错,但是即使我应用了它,仍然抛出:"从对象类型System.Data.DataColumn到已知的托管提供程序本机类型不存在映射。"
Clipboard01.jpg
 
Last edited:

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
我在您的文章中看到,DataAdapter在第一次分配时使用了Select查询,为什么?我不需要那个,因为这让我感到困惑,没有想到要使用它。

这是为什么我多次拒绝发布代码的一个完美示例。当人们看到代码时,他们想要阅读代码-甚至可能在不阅读代码的情况下进行复制和粘贴-而忽略其他所有内容。我在同一篇文章中特别指出:
我还应该指出,您实际上也不需要SelectCommand和FillSchema调用。如果愿意,您可以自己构建DataTable模式。
您只是感到困惑,因为您没有阅读我为您提供的信息,而这浪费了您自己的时间和时间。

无论如何,正如我所说,您需要从DataTable中获取DataRow,因为这是数据所在的位置。就像在数据库中,行包含由列描述的数据一样,DataRows也包含由DataColumns描述的数据。

另一方面,您担心要花时间根据我的建议进行更改,但是很高兴浪费时间写出所有这样的参数:
command.Parameters.Add(new SqlParameter("@sPersonnelCode", System.Data.SqlDbType.VarChar, 3));
// ...
command.Parameters["@sPersonnelCode"].Value = strPersonnelCode;
当您可以这样做时:
command.Parameters.Add("@sPersonnelCode", SqlDbType.VarChar, 3)).Value = strPersonnelCode;
或者,当数据类型合适时,只需执行以下操作:
command.Parameters.AddWithValue("@nRecordType", 1);
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
just this:
command.Parameters.AddWithValue("@nRecordType", 1);

我已经在上面尝试过了,但是我面对这个问题"从对象类型System.Data.DataColumn到已知的托管提供程序本机类型不存在映射。"
因此,我必须深入研究找出可能阻碍我前进的数据类型冲突。

jmcilhinney:
感谢您的帮助。你真的帮了我很多次
 
Last edited:

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
我必须首先从此方法返回DataRow。实际上,这个想法很容易做到,下面为您提供完整的建议。

// copying dt datatable to another datatable to find(Select) exact row of data which desired.
        private DataTable SelectRows(DataTable table1)
        {
            DataTable takas = new DataTable();
            takas.Columns.Add(new DataColumn("Tezgah", typeof(string)));
            takas.Columns.Add(new DataColumn("TezgahAdi", typeof(string)));
            takas.Columns.Add(new DataColumn("OperationCode", typeof(string)));
            takas.Columns.Add(new DataColumn("OperationName", typeof(string)));
            takas.Columns.Add(new DataColumn("ItemCode", typeof(string)));
            takas.Columns.Add(new DataColumn("ItemDescription", typeof(string)));
            takas.Columns.Add(new DataColumn("JobOrder", typeof(string)));
            takas.Columns.Add(new DataColumn("Evrak", typeof(string)));
            takas.Columns.Add(new DataColumn("QTY", typeof(int)));
            takas.Columns.Add(new DataColumn("SONumber", typeof(string)));
            takas.Columns.Add(new DataColumn("SONumberItemCode", typeof(string)));
            takas.Columns.Add(new DataColumn("LatestStarting", typeof(DateTime)));
            takas.Columns.Add(new DataColumn("LatestFinishing", typeof(DateTime)));

            DataRow[] result = table1.Select("Tezgah = '" + splitchar + "'");
            foreach (DataRow row in result) 
            {
                takas.Rows.Add(
                    row["Tezgah"], 
                    row["TezgahAdi"], 
                    row["OperationCode"], 
                    row["OperationName"], 
                    row["ItemCode"], 
                    row["ItemDescription"],
                    row["JobOrder"],
                    row["Evrak"],
                    row["QTY"],
                    row["SONumber"],
                    row["SONumberItemCode"],
                    row["LatestStarting"],
                    row["LatestFinishing"]
                    );
            }
            return takas;
        }
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
几分钟后,我才使用了它;现在我有一个DataRow :)

        {
            DataTable takas = new DataTable();
            takas.Columns.Add(new DataColumn("Tezgah", typeof(string)));
            .....

            DataRow[] result = table1.Select("Tezgah = '" + splitchar + "'");
            foreach (DataRow row in result) 
            {
                ......
            }
            return takas.Rows[0];
        }
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
几分钟后,我才使用了它;现在我有一个DataRow :)

        {
            DataTable takas = new DataTable();
            takas.Columns.Add(new DataColumn("Tezgah", typeof(string)));
            .....

            DataRow[] result = table1.Select("Tezgah = '" + splitchar + "'");
            foreach (DataRow row in result) 
            {
                ......
            }
            return takas.Rows[0];
        }

额外的DataTable到底有什么用?为什么不只是这样:
DataRow result = table1.Select("Tezgah = '" + splitchar + "'").FirstOrDefault();
这将返回第一个匹配项;如果没有匹配项,则返回null。如果永远不会有多个匹配项,请使用SingleOrDefault。如果总是有至少一场比赛,请使用“第一”。如果总有一场比赛,请使用单打。如果总是存在一个或多个匹配项,那么您也可以只索引数组:
DataRow result = table1.Select("Tezgah = '" + splitchar + "'")[0];
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
额外的DataTable到底有什么用?为什么不只是这样:
DataRow result = table1.Select("Tezgah = '" + splitchar + "'").FirstOrDefault();
这将返回第一个匹配项;如果没有匹配项,则返回null。如果永远不会有多个匹配项,请使用SingleOrDefault。如果总是有至少一场比赛,请使用“第一”。如果总有一场比赛,请使用单打。如果总是存在一个或多个匹配项,那么您也可以只索引数组:
DataRow result = table1.Select("Tezgah = '" + splitchar + "'")[0];
总是会有一行,但根据您的建议,我最好使用FirstOrDefault()以获得更多好处,因为可能还会有另一个相同的地方"Tezgah" = "TerminalCode"这可能来自普及SQL。一切都始于我在名为dt的项目的DataTable中检索到的Pervasive SQL数据。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
总是会有一行,但根据您的建议,我最好使用FirstOrDefault()以获得更多好处,因为可能还会有另一个相同的地方"Tezgah" = "TerminalCode"这可能来自普及SQL。一切都始于我在名为dt的项目的DataTable中检索到的Pervasive SQL数据。

如果总有至少一场比赛,那么,正如我已经说过的,您将致电First。这"OrDefault"部分是如果列表中没有项目,则不返回任何内容。您已经说过,列表中总会有一个项目,因此您不需要"OrDefault"。调用这四种方法中的哪一种从来没有任何歧义:

单项:列表中始终只有一个项目。
SingleOrDefault:列表中最多只能有一项,但可能没有。
首先:列表中始终至少有一个项目,并且可能会更多。
FirstOrDefault:列表中可能有零个,一个或多个项目。
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
如果总有至少一场比赛,那么,正如我已经说过的,您将致电First。这"OrDefault"部分是如果列表中没有项目,则不返回任何内容。您已经说过,列表中总会有一个项目,因此您不需要"OrDefault"。调用这四种方法中的哪一种从来没有任何歧义:

单项:列表中始终只有一个项目。
SingleOrDefault:列表中最多只能有一项,但可能没有。
首先:列表中始终至少有一个项目,并且可能会更多。
FirstOrDefault:列表中可能有零个,一个或多个项目。

有趣的是,另一种方法带来了重要的一点,在您的情况下,不需要在下面进行介绍。
// copying dt datatable to another datatable to find(Select) exact row of data which desired.
        private DataRow SelectRows(DataTable table1)
        {
            //DataTable takas = new DataTable();
            //takas.Columns.Add(new DataColumn("Tezgah", typeof(string)));
            //takas.Columns.Add(new DataColumn("TezgahAdi", typeof(string)));
            //takas.Columns.Add(new DataColumn("OperationCode", typeof(string)));
            //takas.Columns.Add(new DataColumn("OperationName", typeof(string)));
            //takas.Columns.Add(new DataColumn("ItemCode", typeof(string)));
            //takas.Columns.Add(new DataColumn("ItemDescription", typeof(string)));
            //takas.Columns.Add(new DataColumn("JobOrder", typeof(string)));
            //takas.Columns.Add(new DataColumn("Evrak", typeof(string)));
            //takas.Columns.Add(new DataColumn("QTY", typeof(int)));
            //takas.Columns.Add(new DataColumn("SONumber", typeof(string)));
            //takas.Columns.Add(new DataColumn("SONumberItemCode", typeof(string)));
            //takas.Columns.Add(new DataColumn("LatestStarting", typeof(DateTime)));
            //takas.Columns.Add(new DataColumn("LatestFinishing", typeof(DateTime)));

            DataRow result = table1.Select("Tezgah = '" + splitchar + "'").Single();

            //foreach (DataRow row in result) 
            //{
            //    takas.Rows.Add(
            //        row["Tezgah"], 
            //        row["TezgahAdi"], 
            //        row["OperationCode"], 
            //        row["OperationName"], 
            //        row["ItemCode"], 
            //        row["ItemDescription"],
            //        row["JobOrder"],
            //        row["Evrak"],
            //        row["QTY"],
            //        row["SONumber"],
            //        row["SONumberItemCode"],
            //        row["LatestStarting"],
            //        row["LatestFinishing"]
            //        );
            //}
            return result;
        }

我将删除该部分并使用以下代码更改一行代码:
DataRow result = table1.Select("Tezgah = '" + splitchar + "'").Single();
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
我注意到了另一件事。在使用下面的方法无法帮助我在SQL Provider中看到某些东西之前,它是SQL Provider与AddWithValue()方法一起使用:
command.Parameters.Add(new SqlParameter("@sDatabase", System.Data.SqlDbType.VarChar, 15));                    command.Parameters["@sPersonnelCode"].Value = strPersonnelCode;



在我使用AddWithValue()更改代码后,使我受益匪浅,可以看到下面的SQL表达式中的问题所在:
Untitled.png

这是一个很好的机会,可以查看问题所在或在可能出现问题的地方给出想法。
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
我最近发现的另一件事是带有DataRow的SQL Expression,这是一个屏幕截图,显示:
another.png
在SQL表达式中使用DataRow时,必须始终使用列名称。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
我最近发现的另一件事是带有DataRow的SQL Expression,这是一个屏幕截图,显示:
查看附件120
在SQL表达式中使用DataRow时,必须始终使用列名称。

不。名称或序数都将同样有效。该代码的问题不是索引,而是您使用字符串连接将文字值插入SQL代码而不是使用参数的事实。
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
我认为现在唯一看到的是:getdatetimeForRecord
我需要将适当的DataTime传递到SQL中。我将对其进行处理。

private void MSSQLInsert()
        {
            // below string can use directly in sql expression without ' (quote-mark) like this ->  " + getdatetimeForRecord + "
            string getdatetimeForRecord = "CURRENT_TIMESTAMP";

            string ConnStrMSSQL = "Data Source=xxxxxx;Initial Catalog=xxxxx;Persist Security Info=True;User ID=xx;Password=xxxxx;";
            using (SqlConnection con = new SqlConnection(ConnStrMSSQL)) 
            {
                con.Open();
                using (SqlCommand command = new SqlCommand(
                    "INSERT INTO tbRecords VALUES (@sPersonnelCode, @sTerminalCode, " +
                    "@sOperationCode, @sItemCode, @sItemDescription, @nJobOrder, @nMPS, " +
                    "@nRecordType, @nQTY, @dStartTime, @dFinishTime, @sSONumber, @sSONumberItemCode, " +
                    "@dLatestStarting, @dLatestFinishing, @sComputerName, @sDatabase);",
                    con)) 
                {
                    command.Parameters.AddWithValue("@sPersonnelCode", strPersonnelCode);
                    command.Parameters.AddWithValue("@sTerminalCode", equalDataRow["Tezgah"]);
                    command.Parameters.AddWithValue("@sOperationCode", equalDataRow["OperationCode"]);
                    command.Parameters.AddWithValue("@sItemCode", equalDataRow["ItemCode"]);
                    command.Parameters.AddWithValue("@sItemDescription", equalDataRow["ItemDescription"]);
                    command.Parameters.AddWithValue("@nJobOrder", equalDataRow["JobOrder"]);
                    command.Parameters.AddWithValue("@nMPS", equalDataRow["Evrak"]);
                    command.Parameters.AddWithValue("@nRecordType", 1);
                    command.Parameters.AddWithValue("@nQTY", 1);
                    command.Parameters.AddWithValue("@dStartTime", getdatetimeForRecord);
                    command.Parameters.AddWithValue("@dFinishTime", getdatetimeForRecord);
                    command.Parameters.AddWithValue("@sSONumber", equalDataRow["SONumber"]);
                    command.Parameters.AddWithValue("@sSONumberItemCode", equalDataRow["SONumberItemCode"]);
                    command.Parameters.AddWithValue("@dLatestStarting", equalDataRow["LatestStarting"]);
                    command.Parameters.AddWithValue("@dLatestFinishing", equalDataRow["LatestFinishing"]);
                    command.Parameters.AddWithValue("@sComputerName", machineName);
                    command.Parameters.AddWithValue("@sDatabase", getDBname);

                    command.ExecuteNonQuery();


getdatetimeForRecord的CURRENT_TIMESTAMP转到带引号的SQL,然后引起问题。.这是证明。
a-1.png
 

索卡斯基

知名会员
已加入
2014年3月3日
留言内容
59
编程经验
Beginner
不。名称或序数都将同样有效。该代码的问题不是索引,而是您使用字符串连接将文字值插入SQL代码而不是使用参数的事实。
我相信通过查看DataRow的角色来指定该问题,可以通过原始方式传递DataColumn(s)数据。您没有通过跳过其列顺序来指定代码的跳过事件。但是在我通过将字符串的名称传递给字符串使用了colomn的名称之后,我实现了正确的目标,这意味着我愿意提供正确的列。所以我这样说。即使它进入耳朵也很奇怪。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,523
地点
悉尼,澳大利亚
编程经验
10+
我相信通过查看DataRow的角色来指定该问题,可以通过原始方式传递DataColumn(s)数据。您没有通过跳过其列顺序来指定代码的跳过事件。但是在我通过将字符串的名称传递给字符串使用了colomn的名称之后,我实现了正确的目标,这意味着我愿意提供正确的列。所以我这样说。即使它进入耳朵也很奇怪。

如果对您不起作用,那是因为您做错了,不是因为它不起作用。您很可能使用了错误的列索引。
 
最佳 底部