【问题标题】:I am getting this error even after declaring scalar variable"'Must declare the scalar variable "@col_shipping_price"即使在声明标量变量“必须声明标量变量“@col_shipping_price”后,我也收到此错误
【发布时间】:2019-05-25 20:55:16
【问题描述】:

我正在尝试从源中获取数据并保存到数据库中,但即使在声明了标量变量之后我也遇到了这个问题。在我尝试过的方法下面找到。我面临的问题:System.Data.SqlClient.SqlException:'必须声明标量变量“@col_shipping_price”。'

class Program
{
    static void Main(string[] args)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(AmazonEnvelope));
        TextReader reader = new StreamReader(@"C:\Users\*********\Desktop\16315550943018039.xml");
        object obj = deserializer.Deserialize(reader);
        AmazonEnvelope XmlData = (AmazonEnvelope)obj;
        reader.Close();
        SqlConnection cnn = new SqlConnection(@"Data Source=ABDUL-TPS\TPSSQLSERVER;Initial Catalog=Zoho_Amz_API;User ID=zohoapiservice;Password=**********");
        cnn.Open();
        for (int i = 0; i < XmlData.Message.Count; i++)
        {
            string sqlquery = "if not exists (select * from tbl_AMZ_API_sample where col_sku like '" + XmlData.Message[i].Order.OrderItem.SKU + "') insert into tbl_AMZ_API_sample(col_amazon_order_id, col_merchant_order_id, col_purchase_date, col_last_updated_date, col_order_status, col_fulfillment_channel, col_sales_channel, col_order_channel, col_url, col_ship_service_level, col_product_name, col_sku, col_asin, col_number_of_items, col_item_status, col_quantity, col_currency, col_item_price, col_item_tax, col_shipping_price, col_shipping_tax, col_gift_wrap_price, col_gift_wrap_tax, col_item_promotion_discount, col_ship_promotion_discount, col_ship_city, col_ship_state, col_ship_postal_code, col_ship_country, col_promotion_ids, col_is_business_order, col_purchase_order_number, col_price_designation, col_fulfilled_by, col_last_update_time) values(@col_amazon_order_id, @col_merchant_order_id, @col_purchase_date, @col_last_updated_date, @col_order_status, @col_fulfillment_channel, @col_sales_channel, @col_order_channel, @col_url, @col_ship_service_level, @col_product_name, @col_sku, @col_asin, @col_number_of_items, @col_item_status, @col_quantity, @col_currency, @col_item_price, @col_item_tax, @col_shipping_price, @col_shipping_tax, @col_gift_wrap_price, @col_gift_wrap_tax, @col_item_promotion_discount, @col_ship_promotion_discount, @col_ship_city, @col_ship_state, @col_ship_postal_code, @col_ship_country, @col_promotion_ids, @col_is_business_order, @col_purchase_order_number, @col_price_designation, @col_fulfilled_by, @col_last_update_time)";
            SqlCommand cmd = new SqlCommand(sqlquery, cnn);

            for (int j = 0; j < XmlData.Message[i].Order.OrderItem.ItemPrice.Component.Count; j++)
            {
                cmd.Parameters.AddWithValue("@col_amazon_order_id", XmlData.Message[i].Order.AmazonOrderID);

                if (XmlData.Message[i].Order.MerchantOrderID == null)
                {
                    cmd.Parameters.AddWithValue("@col_merchant_order_id", DBNull.Value);
                }
                else
                {
                    cmd.Parameters.AddWithValue("@col_merchant_order_id", XmlData.Message[i].Order.MerchantOrderID);
                }
                cmd.Parameters.AddWithValue("@col_purchase_date", XmlData.Message[i].Order.PurchaseDate);
                cmd.Parameters.AddWithValue("@col_last_updated_date", Global.unique.ToString());
                cmd.Parameters.AddWithValue("@col_order_status", XmlData.Message[i].Order.OrderStatus);
                cmd.Parameters.AddWithValue("@col_fulfillment_channel", XmlData.Message[i].Order.FulfillmentData.FulfillmentChannel);
                cmd.Parameters.AddWithValue("@col_sales_channel", XmlData.Message[i].Order.SalesChannel);
                cmd.Parameters.AddWithValue("@col_ship_service_level", XmlData.Message[i].Order.FulfillmentData.ShipServiceLevel);
                cmd.Parameters.AddWithValue("@col_product_name", XmlData.Message[i].Order.OrderItem.ProductName);
                cmd.Parameters.AddWithValue("@col_sku", XmlData.Message[i].Order.OrderItem.SKU);
                cmd.Parameters.AddWithValue("@col_asin", XmlData.Message[i].Order.OrderItem.ASIN);
                cmd.Parameters.AddWithValue("@col_number_of_items", XmlData.Message[i].Order.OrderItem.NumberOfItems);
                cmd.Parameters.AddWithValue("@col_item_status", XmlData.Message[i].Order.OrderItem.ItemStatus);
                cmd.Parameters.AddWithValue("@col_quantity", XmlData.Message[i].Order.OrderItem.Quantity);
                cmd.Parameters.AddWithValue("@col_currency", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Currency);
                switch (XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Type)
                {
                    case "Principal":
                        cmd.Parameters.AddWithValue("@col_item_price", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        cmd.Parameters.AddWithValue("@col_item_tax", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        break;
                    case "Shipping":
                        cmd.Parameters.AddWithValue("@col_shipping_price", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        break;
                    case "GiftWrap":
                        cmd.Parameters.AddWithValue("@col_gift_wrap_price", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        break;
                    case "Shipping-Tax":
                        cmd.Parameters.AddWithValue("@col_shipping_tax", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        break;
                    default:
                        cmd.Parameters.AddWithValue("@col_gift_wrap_tax", XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Amount.Text);
                        break;
                }
                if (XmlData.Message[i].Order.OrderItem.Promotion == null)
                {
                    cmd.Parameters.AddWithValue("@col_item_promotion_discount", 0);
                    cmd.Parameters.AddWithValue("@col_ship_promotion_discount", 0);
                    cmd.Parameters.AddWithValue("@col_promotion_ids", 0);
                }

                else
                {
                    cmd.Parameters.AddWithValue("@col_item_promotion_discount", XmlData.Message[i].Order.OrderItem.Promotion.ItemPromotionDiscount);
                    cmd.Parameters.AddWithValue("@col_ship_promotion_discount", XmlData.Message[i].Order.OrderItem.Promotion.ShipPromotionDiscount);
                    cmd.Parameters.AddWithValue("@col_promotion_ids", XmlData.Message[i].Order.OrderItem.Promotion.PromotionIDs);
                }

                cmd.Parameters.AddWithValue("@col_ship_city", XmlData.Message[i].Order.FulfillmentData.Address.City);
                cmd.Parameters.AddWithValue("@col_ship_state", XmlData.Message[i].Order.FulfillmentData.Address.State);
                cmd.Parameters.AddWithValue("@col_ship_postal_code", XmlData.Message[i].Order.FulfillmentData.Address.PostalCode);
                cmd.Parameters.AddWithValue("@col_ship_country", XmlData.Message[i].Order.FulfillmentData.Address.Country);
                cmd.Parameters.AddWithValue("@col_is_business_order", XmlData.Message[i].Order.IsBusinessOrder);
                cmd.Parameters.AddWithValue("@col_purchase_order_number", XmlData.Message[i].Order.PurchaseOrderNumber);
                cmd.Parameters.AddWithValue("@col_price_designation", XmlData.Message[i].Order.OrderItem.PriceDesignation);
                cmd.Parameters.AddWithValue("@col_fulfilled_by", XmlData.Message[i].Order.FulfilledBy);
                cmd.Parameters.AddWithValue("@col_Order_Channel", DBNull.Value);
                cmd.Parameters.AddWithValue("@col_url", DBNull.Value);
                Console.WriteLine(XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Type);
                cmd.ExecuteNonQuery();
            }

        }
        Console.ReadKey();
    }
}

请有人帮忙。

【问题讨论】:

  • 当你清楚地知道参数时为什么要注入XmlData.Message的值(虽然我也建议使用Parameters.Add而不是Parameters.AddWithValue
  • @col_shipping_price 的声明在 Switch 中,但它始终在您的 SQL 语句中。

标签: sql-server c#-4.0


【解决方案1】:

你显然知道如何使用参数化查询,那么为什么不在查询的SELECT 部分使用它呢:

... like '" + XmlData.Message[i].Order.OrderItem.SKU + "' ...

您还应该在那里使用参数。除非XmlData.Message[i].Order.OrderItem.SKU 包含通配符,否则LIKE 可以更改为=,这似乎不太可能。

关于你的问题:

您在查询的INSERT 部分中有@col_shipping_price,显然是作为参数。但是,只有在switch() 中的XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].TypeShipping 时,才设置此参数。也就是说,在所有其他情况下,@col_shipping_price 在查询中保持原样,不会被替换。 SQL Server 认为它是一个变量,并理所当然地抱怨它没有被声明。你们中的一些其他参数可能会出现同样的问题。

这里有一些选择。

  1. 一直替换所有参数。如果您没有实际价值,可能使用DBNull。除非对应该起作用的列没有空约束。如果你这样做,也不需要在每次迭代中重建查询。创建一次,可选Prepare() 它,然后在迭代中更改参数的值。性能可能会因此受益。
  2. 根据XmlData.Message[i].Order.OrderItem.ItemPrice.Component[j].Type 构建不同的查询。这样您就可以简单地将未使用参数的占位符排除在外。

并且你在使用AddWithValue()时要小心,甚至完全避免使用它。它需要猜测数据库上列的数据类型,有时会惨遭失败并产生有趣的错误。更好地使用带有显式类型参数的 Add() 重载。关于这个主题的阅读:"AddWithValue is Evil"

【讨论】:

    猜你喜欢
    • 2013-01-16
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多