使用参数时TSQL抛出算术溢出,但不是没有参数?

时间:2017-09-17 10:54:05

标签: c# .net sql-server tsql azure

我正在尝试保存某些记录,这些记录的小数位数不确定但从不大于4或10.我最近从MySQL迁移到SQL Azure,我的代码运行问题;它抛出算术溢出但我无法弄清楚在哪里。 (控制台应用程序,.NET 4.6)

cmd.CommandText = "INSERT INTO [crypto].[ticker" + Toggles.tablePostFix + "] ([pair], [ask_price], [ask_volume], [aks_wholelotvolume], [bid_price], [bid_volume], " +
                  "[bid_wholelotvolume], [lasttrade_price], [lasttrade_volume], [volume_today], [volume_24h], [trades_today], [trades_24h], " +
                  "[VWAP_today], [VWAP_24h], [open], [low_today], [low_24h], [high_today], [high_24h], [serverTime], [base_currency], [quote_currency]) " +
                  "VALUES (N'" +
                        ticks.Key + "', " +
                        "CAST(@ask_price AS Decimal(15, 10)), " +
                        "CAST(@ask_volume AS Decimal(10, 4)), " +
                        "CAST(@aks_wholelotvolume AS Decimal(10, 4)), " +

                        "CAST(@bid_price AS Decimal(15, 10)), " +
                        "CAST(@bid_volume AS Decimal(10, 4)), " +
                        "CAST(@bid_wholelotvolume AS Decimal(10, 4)), " +

                        "CAST(@lasttrade_price AS Decimal(15, 10)), " +
                        "CAST(@lasttrade_volume AS Decimal(10, 4)), " +
                        "CAST(@volume_today AS Decimal(10, 4)), " +

                        "CAST(@volume_24h AS Decimal(10, 4)), " +
                        "@trades_today, " +
                        "@trades_24h, " +
                        "CAST(@VWAP_today AS Decimal(15, 10)), " +
                        "CAST(@VWAP_24h AS Decimal(15, 10)), " +
                        "CAST(@open AS Decimal(15, 10)), " +
                        "CAST(@low_today AS Decimal(15, 10)), " +
                        "CAST(@low_24h AS Decimal(15, 10)), " +
                        "CAST(@high_today AS Decimal(15, 10)), " +
                        "CAST(@high_24h AS Decimal(15, 10)), " +
                        //"@serverTime, " +
                        //"@base_currency, " +
                        //"@quote_currency);";
                        "N'" + servertijd.ToString() + "', N'" + basecur + "', N'" + quotecur + "');";

cmd.Prepare();

//cmd.Parameters.AddWithValue("@pair", ticks.Key);
cmd.Parameters.AddWithValue("@ask_price", values.Ask[0]);
cmd.Parameters.AddWithValue("@ask_volume", values.Ask[1]);
cmd.Parameters.AddWithValue("@aks_wholelotvolume", values.Ask[2]);
cmd.Parameters.AddWithValue("@bid_price", values.Bid[0]);
cmd.Parameters.AddWithValue("@bid_volume", values.Bid[1]);
cmd.Parameters.AddWithValue("@bid_wholelotvolume", values.Bid[2]);
cmd.Parameters.AddWithValue("@lasttrade_price", values.Closed[0]);
cmd.Parameters.AddWithValue("@lasttrade_volume", values.Closed[1]);
cmd.Parameters.AddWithValue("@volume_today", values.Volume[0]);
cmd.Parameters.AddWithValue("@volume_24h", values.Volume[1]);
cmd.Parameters.AddWithValue("@trades_today", values.Trades[0]);
cmd.Parameters.AddWithValue("@trades_24h", values.Trades[1]);
cmd.Parameters.AddWithValue("@VWAP_today", values.VWAP[0]);
cmd.Parameters.AddWithValue("@VWAP_24h", values.VWAP[1]);
cmd.Parameters.AddWithValue("@open", values.Open);
cmd.Parameters.AddWithValue("@low_today", values.Low[0]);
cmd.Parameters.AddWithValue("@low_24h", values.Low[1]);
cmd.Parameters.AddWithValue("@high_today", values.High[0]);
cmd.Parameters.AddWithValue("@high_24h", values.High[1]);
//cmd.Parameters.AddWithValue("@serverTime", servertijd.ToString());
//cmd.Parameters.AddWithValue("@base_currency", basecur);
//cmd.Parameters.AddWithValue("@quote_currency", quotecur);

string tekst = cmd.CommandText;

for(int i = 0; i < cmd.Parameters.Count; i++)
{
    tekst = tekst.Replace(cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value.ToString());
}

Debug.WriteLine(tekst);
cmd.ExecuteNonQuery();

我曾经用参数插入所有内容,但我已经更改了非数字值([pair],[base_currency],[serverTime]和[quote_currency])。原因是代码的低位,我使用for循环来创建一个我可以测试自己的SQL语句。

这里有踢球者;当我调试这个并且我复制字符串'tekst'时,我得到了这个;

INSERT INTO [crypto].[tickertest] ([pair], [ask_price], [ask_volume], [aks_wholelotvolume], [bid_price], [bid_volume], [bid_wholelotvolume], [lasttrade_price], [lasttrade_volume], [volume_today], [volume_24h], [trades_today], [trades_24h], [VWAP_today], [VWAP_24h], [open], [low_today], [low_24h], [high_today], [high_24h], [serverTime], [base_currency], [quote_currency]) 
VALUES (N'BCHEUR', CAST(359.600000 AS Decimal(15, 10)), CAST(114 AS Decimal(10, 4)), CAST(114.000 AS Decimal(10, 4)), CAST(359.300000 AS Decimal(15, 10)), CAST(1 AS Decimal(10, 4)), CAST(1.000 AS Decimal(10, 4)), CAST(359.600000 AS Decimal(15, 10)), CAST(4.11400000 AS Decimal(10, 4)), CAST(1474.09361766 AS Decimal(10, 4)), CAST(4159.61657024 AS Decimal(10, 4)), 913, 3206, CAST(356.680012 AS Decimal(15, 10)), CAST(362.558505 AS Decimal(15, 10)), CAST(376.000000 AS Decimal(15, 10)), CAST(344.500000 AS Decimal(15, 10)), CAST(344.500000 AS Decimal(15, 10)), CAST(377.200000 AS Decimal(15, 10)), CAST(382.400000 AS Decimal(15, 10)), N'9/17/2017 10:36:51 AM', N'BCH', N'EUR');

那只是有效吗?那么,我在这里输了,为什么它在不使用参数时工作但是当我使用参数时它会抛出这个算术溢出?

PS。所有十进制列都是DECIMAL(x,y)类型的铸造语句(所以十进制(10,4)或十进制(15,10)。

完整错误:

  

将数值转换为数据类型为数字的算术溢出错误。   该语句已被终止.at System.Data.SqlClient.SqlConnection.OnError(SqlException异常,Boolean breakConnection,Action 1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action 1 wrapCloseInAction)      在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)      在System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj,Boolean&amp; dataReady)      在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString,Boolean isInternal,Boolean forDescribeParameterEncryption)      at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async,Int32 timeout,Task&amp; task,Boolean asyncWrite,Boolean inRetry,SqlDataReader ds,Boolean describeParameterEncryptionRequest)      at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method,TaskCompletionSource 1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource 1 completion,String methodName,Boolean sendToPipe,Int32 timeout,Boolean&amp; usedCache,Boolean asyncWrite,Boolean inRetry )      在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()      at COnsolePrutsApp.Program.SaveTicker(Dictionary 2 ticker, Int32 serverTime, Dictionary 2 assetspairs,Dictionary`2 assetinfo)在C:\ Users \ jarro \ OneDrive \ Documents \ Visual Studio 2017 \ Projects \ COnsolePrutsApp \ COnsolePrutsApp \ Program.cs:第163行< / p>

第163行

cmd.ExecuteNonQuery() 

修改

我也尝试将AddWithValue更改为:

cmd.Parameters.Add("@ask_price", SqlDbType.Decimal).Value = values.Ask[0];

我已经仔细检查过我输入小数和int(后者仅用于@trades_today和@trades_24h)。但仍然是同样的错误。 (从这里开始提出这个想法:SO question on the matter

编辑2 我找到了;但似乎很奇怪这在MySQL中没有发生;确实有一个值不符合十进制(10,4)(实际值类似于3425343.0045),因为它在小数点的左边有一个到多个数字(其中最大值是6)。我已经将我的所有列升级到Decimal(20,10)只是为了摆脱这种烦恼,现在它起作用了:)

1 个答案:

答案 0 :(得分:0)

尝试使用:

SELECT CONVERT(DECIMAL(38,20),34.654) a, CONVERT(DECIMAL(38,20),34.654) b

然后尝试:

SELECT CONVERT(DECIMAL(15,10),CONVERT(DECIMAL(15,10),34.654)) a, CONVERT(DECIMAL(15,4),CONVERT(DECIMAL(15,4),34.654)) b

第一个应该工作(除非没有实数数据)。如果第二个不起作用(并且第一个不起作用)那么你需要具有更高精度的数字。 另外:如果您的源数据不是数字或类似的数据类型,例如varchar,确保你有正确的字符作为小数分隔符。