以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XML 与 数据库 』  (http://bbs.xml.org.cn/list.asp?boardid=17)
----  XML格式存储中文字符到数据库出错 !高手来帮帮![求助]  (http://bbs.xml.org.cn/dispbbs.asp?boardid=17&rootid=&id=38910)


--  作者:llnwzw
--  发布时间:10/15/2006 12:31:00 AM

--  XML格式存储中文字符到数据库出错 !高手来帮帮![求助]
我做了个 商务网站  在购物车模块的 定单信息存储到数据库时我是用XML格式存储用户定单信息的  但是发现用户输入的是中文的话 在点击提交后 存储数据就出错了 英文和数字字符就没有问题!

不知道是什么原因  希望高手来帮帮!谢谢


--  作者:llnwzw
--  发布时间:10/15/2006 12:35:00 AM

--  
我是用C#/ASP。net做的网站 !
--  作者:llnwzw
--  发布时间:10/15/2006 12:48:00 AM

--  
using System;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;

namespace digitalshop.Components {
 /// <summary>
 /// Online orders transactions.
 /// </summary>
 public class Order {
  /// <summary>
  /// Adds a new order to the database.
  /// </summary>
  /// <param name="xml">The order xml doc.</param>
  /// <returns>The new order id.</returns>
  public int Add(string xml) {
   try {
    // create data object and params
    Database data = new Database();
    SqlParameter[] prams = { data.MakeInParam("@xml", SqlDbType.VarChar, 8000, xml) };
    
    // run the stored procedure
    return data.RunProc("upOrdersAdd", prams);
   }
   catch (Exception ex) {
    Error.Log(ex.ToString());
    return 0;
   }
  }

  /// <summary>
  /// Gets the list of orders for a specified user.
  /// </summary>
  /// <param name="userid">The customer's user id.</param>
  /// <returns>A SQL Data Reader containing the list of orders.</returns>
  public SqlDataReader GetOrder(string userid) {
   // create data object and params
   SqlDataReader dataReader = null;
   Database data = new Database();

   SqlParameter[] prams = { data.MakeInParam("@userid", SqlDbType.VarChar, 80, userid) };
   
   try {
    // run the stored procedure
    data.RunProc("upOrdersGet", prams, out dataReader);
    return dataReader;
   }
   catch (Exception ex) {
    Error.Log(ex.ToString());
    return null;
   }
  }

  /// <summary>
  /// Returns the order status for the given order number.
  /// </summary>
  /// <param name="orderid">The customer's order number.</param>
  /// <returns>If the order status is valid a string with the order
  /// status is returned, otherwise null is returned.</returns>
  public string GetOrderStatus(string orderid) {
   string orderStatus;

   // create data object and params
   Database data = new Database();

   SqlParameter[] prams = {
    data.MakeInParam("@orderid", SqlDbType.VarChar, 80, orderid),
    data.MakeOutParam("@OrderStatus", SqlDbType.Char, 2)
   };

   try {
    data.RunProc("upOrderStatusGet", prams);    // run the stored procedure
    orderStatus = (string) prams[1].Value;      // get the output param value

    // if the order status is an empty string, then the lookup failed
    if (orderStatus == string.Empty)
     return null;
    else
     return orderStatus;
   }
   catch (Exception ex) {
    Error.Log(ex.ToString());
    return null;
   }
  }
 }
}


这是Order.cs    封装 定单类和定单操作事物的代码


--  作者:llnwzw
--  发布时间:10/15/2006 12:49:00 AM

--  
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using digitalshop.Components;

namespace digitalshop.Web {
 /// <summary>
 /// Process the order and display summary.
 /// </summary>
 public class OrderProcess : System.Web.UI.Page {
  protected System.Web.UI.WebControls.Label lblOrderID;
  protected System.Web.UI.WebControls.Label lblDate;
  protected System.Web.UI.WebControls.Label lblStatus;
  protected System.Web.UI.WebControls.Label lblShipAdr1;
  protected System.Web.UI.WebControls.Label lblShipAdr2;
  protected System.Web.UI.WebControls.Label lblShipCity;
  protected System.Web.UI.WebControls.Label lblShipState;
  protected System.Web.UI.WebControls.Label lblShipPostalCode;
  protected System.Web.UI.WebControls.Label lblCardType;
  protected System.Web.UI.WebControls.Label lblCardNumber;
  protected System.Web.UI.WebControls.Label lblCardDate;
  protected System.Web.UI.WebControls.DataGrid dataGrid;
  protected System.Web.UI.WebControls.Label lblAccount;

  public OrderProcess() {
   Page.Init += new System.EventHandler(Page_Init);
  }

  private void Page_Load(object sender, System.EventArgs e) {
   // make sure we really have items in the cart
   ShoppingCart cart = (ShoppingCart)Session["ShoppingCartSession"];
   if (cart.Count == 0)
    Response.Redirect("Cart.aspx");
    
   // We have to use a manual datagrid instead of the cart user control
   // since the usercontrol displays the content of the shoppingcart
   // session object... but its Load event is called after all of the
   // Page events are called. By the time the usercontrol's Load event
   // is called, the shoppingcart session object is empty.
   dataGrid.Columns[4].FooterText = cart.Total.ToString("c");
   dataGrid.DataSource = cart.GetItems();
   dataGrid.DataBind();

   // determine who is logged in
   Debug.Assert(Request.Cookies["CustomerID"] != null);
   string userID = (string)Request.Cookies["CustomerID"].Value;

   // add order to database
   DateTime orderDate = DateTime.Now;
   int orderID = AddOrder(userID, orderDate.ToString());
   
   // hook up results
   lblDate.Text = orderDate.ToLongDateString();
   lblAccount.Text = userID;
   lblOrderID.Text = orderID.ToString();
   lblStatus.Text = "P";
   
   // credit card
   Hashtable adr = (Hashtable)Session["ShoppingAddressSession"];
   Debug.Assert(adr != null);   
   lblCardType.Text = (string)adr["CardType"];
   lblCardNumber.Text = (string)adr["CardNumber"];
   lblCardDate.Text = (string)adr["CardExpireMonth"] + "/" + (string)adr["CardExpireYear"];

   // clear shopping cart
   cart.ClearCart();    
  }

  // add order to database
  private int AddOrder(string userID, string orderDate) {
   // get shopping cart
   ShoppingCart cart = (ShoppingCart)Session["ShoppingCartSession"];
   Debug.Assert(cart != null);

   // create xml doc to pass down to stored proc, this xml doc contains
   // one main <Orders> section and multiple <LineItems> sections
   string xml = "<Orders " + GetOrdersXML(userID, orderDate) + ">" +
    cart.GetLineItemsXML() + "</Orders>";

   // add this order to the database, get the new order id back   
   Order order = new Order();
   int id = order.Add(xml);
   return id;
  }

  // returns the attriubutes for the Orders xml section  
  private string GetOrdersXML(string userID, string orderDate) {
   // use session objects to create xml string
   Hashtable adr = (Hashtable)Session["ShoppingAddressSession"];
   Debug.Assert(adr != null);   

   ShoppingCart cart = (ShoppingCart)Session["ShoppingCartSession"];
   Debug.Assert(cart != null);

   // total price
   string totalPrice = cart.Total.ToString();

   // create attribute string
   string xml = "userid='" + userID +
    "' orderdate='" + orderDate +
    "' shiptofirstname='" + adr["Ship_FirstName"] +
    "' shiptolastname='" +adr["Ship_LastName"] +
    "' shipaddr1='" + adr["Ship_Address1"] +
    "' shipaddr2='" + adr["Ship_Address2"] +
    "' shipcity='" + adr["Ship_City"] +
    "' shipstate='" + adr["Ship_State"] +
    "' shipzip='" + adr["Ship_PostalCode"] +
    "' shipcountry='" + adr["Ship_Country"] +
    "' billtofirstname='" + adr["Bill_FirstName"] +
    "' billtolastname='" +adr["Bill_LastName"] +
    "' billaddr1='" + adr["Bill_Address1"] +
    "' billaddr2='" + adr["Bill_Address2"] +
    "' billcity='" + adr["Bill_City"] +
    "' billstate='" + adr["Bill_State"] +
    "' billzip='" + adr["Bill_PostalCode"] +
    "' billcountry='" + adr["Bill_Country"] +
    "' creditcard='" + adr["CardNumber"] +
    "' exprdate='" + adr["CardExpireMonth"] + "/" + adr["CardExpireYear"] +
    "' cardtype='" + adr["CardType"] +
    "' courier='UPS" +
    "' totalprice='" + totalPrice +
    "' locale='US_en'";

   return xml;
  }

  private void Page_Init(object sender, EventArgs e) {
   //
   // CODEGEN: This call is required by the ASP.NET Web Form Designer.
   //
   InitializeComponent();
  }

  #region Web Form Designer generated code
  /// <summary>
  /// Required method for Designer support - do not modify
  /// the contents of this method with the code editor.
  /// </summary>
  private void InitializeComponent()
  {    
   this.Load += new System.EventHandler(this.Page_Load);

  }
  #endregion
 }
}

这是定单生成的代码! 就是这里出的问题!


--  作者:llnwzw
--  发布时间:10/15/2006 12:54:00 AM

--  
还有 个数据库的 存储过程  代码如下:


-------------------------------------------------------------------------------
-- upOrdersAdd
-------------------------------------------------------------------------------
/******************************************************************************
 Add order to database. Example of using this stored proc is shown below.
 
 declare @xml varchar(8000)
 set @xml =
  '
  <Orders
  userid="j2ee" orderdate="1/1/2001"
  shipaddr1="1234 West Branch" shipaddr2=""
  shipcity="Liveoak" shipstate="Texas"
  shipzip="12345" shipcountry="USA"
  billaddr1="5678 East Branch" billaddr2="Building C"
  billcity="Madrone" billstate="Utah"
  billzip="99999" billcountry="USA"
  courier="UPS" totalprice="57.50"
  billtofirstname="Fred" billtolastname="Derfy"
  shiptofirstname="Bob" shiptolastname="Black"
  creditcard="111-222-333" exprdate="9/2002"
  cardtype="Visa" locale="US_en">
    <LineItem itemid="EST-1" linenum="1" quantity="4" unitprice="5.00" />
    <LineItem itemid="EST-2" linenum="2" quantity="5" unitprice="7.00" />
    <LineItem itemid="EST-3" linenum="3" quantity="2" unitprice="1.25" />
  </Orders>
  '

 exec upOrderAdd @xml
 
*******************************************************************************/
CREATE PROCEDURE upOrdersAdd
(
    @xml                 varchar(8000)
)
AS

    DECLARE @idoc int  -- xml doc
    DECLARE @orderid int -- new order

    -- parse xml doc
    EXEC sp_xml_preparedocument @idoc output, @xml


    SET NOCOUNT ON
    DECLARE @CurrentError int

    -- start transaction, updating three tables
    BEGIN TRANSACTION

    -- add new order to Orders table
    INSERT INTO Orders
    SELECT userid, orderdate, shipaddr1, shipaddr2, shipcity, shipstate,
           shipzip, shipcountry, billaddr1, billaddr2, billcity, billstate, billzip,
           billcountry, courier, totalprice, billtofirstname, billtolastname,
           shiptofirstname, shiptolastname, creditcard, exprdate, cardtype, locale
    FROM OpenXML(@idoc, '/Orders')
    WITH Orders

    -- check for error
    SELECT @CurrentError = @@Error

    IF @CurrentError != 0
        BEGIN
            GOTO ERROR_HANDLER
        END

    -- get new order id
    SELECT @orderid = @@IDENTITY

    -- add line items to LineItem table
    INSERT INTO LineItem
    SELECT @orderid, linenum, itemid, quantity, unitprice
    FROM OpenXML(@idoc, '/Orders/LineItem')
    WITH LineItem

    -- check for error
    SELECT @CurrentError = @@Error

    IF @CurrentError != 0
        BEGIN
            GOTO ERROR_HANDLER
        END

    -- add status to OrderStatus table
    INSERT INTO OrderStatus
    SELECT @orderid, @orderid, getdate(), 'P'

    -- check for error
    SELECT @CurrentError = @@Error

    IF @CurrentError != 0
        BEGIN
            GOTO ERROR_HANDLER
        END

    -- update inventory
    UPDATE Inventory
    SET Inventory.qty = Inventory.qty - LineItem.quantity
    FROM OpenXML(@idoc, '/Orders/LineItem')
    WITH LineItem
    WHERE Inventory.itemid=LineItem.itemid

    -- check for error
    select @CurrentError = @@Error

    IF @CurrentError != 0
        BEGIN
            GOTO ERROR_HANDLER
        END

    -- end of transaction
    COMMIT TRANSACTION

    SET NOCOUNT OFF

    -- done with xml doc
    EXEC sp_xml_removedocument @idoc

    -- return the new order
    RETURN @orderid

    ERROR_HANDLER:
        ROLLBACK TRANSACTION
        SET NOCOUNT OFF    
        RETURN 0    
    
GO


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
17,027.340ms