2

几天来我一直试图找到这个问题的答案,但似乎无法得到它。

我有一个从 Web 服务获得的 xml 字符串,我需要将其存储在我的 sql server 2012 中。

xml 字符串可以大到 100k。

我有下表

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[TempXML](
[id] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
[MyXML] [varbinary](max) NOT NULL,
CONSTRAINT [PK_TempXML] PRIMARY KEY CLUSTERED 
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,         ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[TempXML] ADD  CONSTRAINT [DF_TempXML_id]  DEFAULT (newid()) FOR [id]
GO

以及以下存储过程

CREATE PROCEDURE [dbo].[InsertXML] 
(   @xml xml)

AS  
BEGIN

SET NOCOUNT ON;
Insert into TempXML
values(NEWID(), @xml)
END 

如果数据大小大于 43752 个字符,我调用 sproc 时,它会删除数据并仅安装 id。

另一方面,如果该字段设置为 nvarchar(max),则在删除整个字符串之前我可以加载的最大值是 65535 char

我正在从 c# 方法调用存储过程

internal static void InsertTempMovie(string xml)
{

{
        xmlSouce = xmlSouce.Replace("&", "&amp");
        xmlSouce = xmlSouce.Replace("'", "'");
        xmlSouce = xmlSouce.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<?xml version=\"1.0\" encoding=\"UTF-16\"?>");


        string xmlSouceEncoded = HttpUtility.HtmlDecode(xmlSouce);

        LinQTestDataContext dbTempXML = new LinQTestDataContext();
        dbTempXML .ExecuteCommand("exec InsertTempXML @xml={0}",xmlSouceEncoded);
    }
}

但是,即使我直接从 sql server 2012 management studio 调用,我也会得到相同的结果

关于我可以上传整个字符串而不被丢弃的任何想法

先感谢您

4

1 回答 1

2

My first recommendation would be: since you have XML data and you want to store it - store it as XML! Why convert it to varbinary? XML is not binary data...

So change your table definition to:

CREATE TABLE [dbo].[TempXML]
(
    [id] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [MyXML] [XML] NOT NULL,

    CONSTRAINT [PK_TempXML] 
    PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Next, you can either use just plain ADO.NET to insert those XML files into your database - something like this:

// define connection and command in using blocks to ensure proper disposal
using(SqlConnection conn = new SqlConnection(yourConnectionString))
using (SqlCommand cmdInsert = new SqlCommand("dbo.InsertXML", conn))
{
    cmdInsert.CommandType = CommandType.StoredProcedure;

    // define your parameters
    cmdInsert.Parameters.Add("@xml", SqlDbType.Xml, int.MaxValue);

    // set the parameter values
    string xmlContents = File.ReadAllText(@"...path to your XML file here.....");
    cmdInsert.Parameters["@xml"].Value = xmlContents;

    // open connection, execute command, close connection
    conn.Open();
    int affected = cmdInsert.ExecuteNonQuery();
    conn.Close();
 }

Or if you're using Linq-to-SQL, then import the stored procedure you're using into your Linq-to-SQL data context model, and then just call that stored procedure on the DataContext class of your model:

// use your DataContext class here - in a using block
using (DataClasses1DataContext ctx = new DataClasses1DataContext())
{
    // load your XML document from a file
    XDocument doc = XDocument.Load(@"....path to your XML file here.....");

    // call the stored procedure that's defined on your DataContext class
    ctx.ProcInsertXML(doc.Root);
}

Both ways, I was able to insert very large XML (500 KB - 2.5 MB) into SQL Server without any problems whatsoever.

于 2013-05-12T18:47:06.930 回答