代码之家  ›  专栏  ›  技术社区  ›  Alex Papadimoulis

stackoverflow导入错误:lob超过2147483647字节?

  •  3
  • Alex Papadimoulis  · 技术社区  · 16 年前

    下载后 September 2009 StackOverflow data-dump 经营布伦特的 import query ,我收到以下消息:

    Msg 7119, Level 16, State 1, Procedure sp_xml_preparedocument, Line 1
    Attempting to grow LOB beyond maximum allowed size of 2,147,483,647 bytes.
    Msg 8179, Level 16, State 5, Procedure usp_ETL_Load_Posts, Line 59
    Could not find prepared statement with handle 0.
    The statement has been terminated.
    Msg 7102, Level 20, State 99, Procedure usp_ETL_Load_Posts, Line 121
    Internal Error: Text manager cannot continue with current statement. 
        Run DBCC CHECKTABLE.
    

    布伦特的查询基于7月份的数据,我怀疑这是9月份数据库更大的结果。

    除了获取旧数据外,还有谁知道如何修复此问题或以其他方式导入数据?

    更新: 我正在运行“版本:Microsoft SQL Server 2005-9.00.1399.06(Intel x86)2005年10月14日00:33:37版权所有(C)1988-2005 Microsoft Corporation Developer Edition on on on Windows NT 5.1(内部版本2600:Service Pack 3)”

    3 回复  |  直到 16 年前
        1
  •  2
  •   Joel Coehoorn    16 年前

    我通过在.NET中编写一个小的控制台应用程序(代码如下)克服了这个问题。它一次导入记录1(甚至不花时间处理sqlbackcopy对象),并在我午休时运行。我忘了给控制台写时间戳,所以我不知道它到底花了多长时间。我的最佳估计是20分钟多一点。请注意,下一个问题是tempdb:保留默认设置后,tempdb在导入期间将增长得非常大。当SQL Server服务完成后,您需要重新启动它。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
    using System.Xml;
    namespace ImportPostsTable
    {
        class Program
        {
            //TODO: pull connection string, data path from app.config or command line
            static string cnString = "Data Source=localhost;Database=SO;Trusted_Connection=True;";
            static string dataPath = @"C:\temp"; 
            static string insertString = "INSERT INTO Posts VALUES (@Id, @PostTypeID, @AcceptedAnswerId, @CreationDate, @Score, @ViewCount, @Body, @OwnerUserId, @OwnerDisplayName, @LastEditorUserId, @LastEditDate, @LastActivityDate, @Title, @Tags, @AnswerCount, @CommentCount, @FavoriteCount, @ClosedDate, @ParentId)";
            static void Main(string[] args)
            {
                Trace.Listeners.Add(new ConsoleTraceListener());
    
                try
                {
                     ImportPosts(dataPath, cnString);
                }
                catch (Exception e)
                {
                    Trace.WriteLine(e.Message);
                    Trace.WriteLine(e.StackTrace);
                }
                Console.ReadKey(true);
            }
    
            public static void ImportPosts(string XmlPath, string ConnectionString)
            {
                using (StreamReader sr = new StreamReader(Path.Combine(XmlPath, "posts.xml")))
                using (XmlTextReader rdr = new XmlTextReader(sr))
                using (SqlConnection cn = new SqlConnection(ConnectionString))
                using (SqlCommand cmd = new SqlCommand(insertString, cn))
                {
                    cmd.Parameters.Add("@Id", SqlDbType.Int);
                    cmd.Parameters.Add("@PostTypeId", SqlDbType.Int);
                    cmd.Parameters.Add("@AcceptedAnswerId", SqlDbType.Int);
                    cmd.Parameters.Add("@CreationDate", SqlDbType.DateTime);
                    cmd.Parameters.Add("@Score", SqlDbType.Int);
                    cmd.Parameters.Add("@ViewCount", SqlDbType.Int);
                    cmd.Parameters.Add("@Body", SqlDbType.NVarChar);
                    cmd.Parameters.Add("@OwnerUserId", SqlDbType.Int);
                    cmd.Parameters.Add("@OwnerDisplayName", SqlDbType.NVarChar, 40);
                    cmd.Parameters.Add("@LastEditorUserId", SqlDbType.Int);
                    cmd.Parameters.Add("@LastEditDate", SqlDbType.DateTime);
                    cmd.Parameters.Add("@LastActivityDate", SqlDbType.DateTime);
                    cmd.Parameters.Add("@Title", SqlDbType.NVarChar, 250);
                    cmd.Parameters.Add("@Tags", SqlDbType.NVarChar, 150);
                    cmd.Parameters.Add("@AnswerCount", SqlDbType.Int);
                    cmd.Parameters.Add("@CommentCount", SqlDbType.Int);
                    cmd.Parameters.Add("@FavoriteCount", SqlDbType.Int);
                    cmd.Parameters.Add("@ClosedDate", SqlDbType.DateTime);
                    cmd.Parameters.Add("@ParentId", SqlDbType.Int);
    
                    Trace.Write(DateTime.Now.ToString() + Environment.NewLine + "Reading");
                    int count = 0;
                    cn.Open();
                    while (rdr.Read())
                    {
                        if (rdr.AttributeCount <= 5) continue; //everything but the xml declaration and the root element will have at least 5 attributes
    
                        cmd.Parameters[0].Value = rdr["Id"];
                        cmd.Parameters[1].Value = rdr["PostTypeId"];
                        cmd.Parameters[2].Value = rdr["AcceptedAnswerId"];
                        cmd.Parameters[3].Value = ParseDate(rdr["CreationDate"]);
                        cmd.Parameters[4].Value = rdr["Score"];
                        cmd.Parameters[5].Value = rdr["ViewCount"];
                        cmd.Parameters[6].Value = rdr["Body"];
                        cmd.Parameters[7].Value = rdr["OwnerUserId"];
                        cmd.Parameters[8].Value = rdr["OwnerDisplayName"];
                        cmd.Parameters[9].Value = rdr["LastEditorUserId"];
                        cmd.Parameters[10].Value = ParseDate(rdr["LastEditDate"]);
                        cmd.Parameters[11].Value = ParseDate(rdr["LastActivityDate"]);
                        cmd.Parameters[12].Value = rdr["Title"];
                        cmd.Parameters[13].Value = rdr["Tags"];
                        cmd.Parameters[14].Value = rdr["AnswerCount"];
                        cmd.Parameters[15].Value = rdr["CommentCount"];
                        cmd.Parameters[16].Value = rdr["FavoriteCount"];
                        cmd.Parameters[17].Value = ParseDate(rdr["ClosedDate"]);
                        cmd.Parameters[18].Value = rdr["ParentId"];
    
                        for (int i = 0; i < cmd.Parameters.Count; i++)
                            if (cmd.Parameters[i].Value == null)
                                cmd.Parameters[i].Value = DBNull.Value;
    
                        cmd.ExecuteNonQuery();
    
                        if (count++ % 5000 == 0) Trace.Write(".");
                    }
                    Trace.WriteLine(string.Format("\n\n{0:d}\nFinished {1} records.", DateTime.Now, count));
                }
            }
    
            public static object ParseDate(string dateValue)
            {
                if (string.IsNullOrEmpty(dateValue)) return DBNull.Value;
                return DateTime.ParseExact(dateValue, "yyyy-MM-ddTHH:mm:ss.fff", null);
            }
        }
    }
    
        2
  •  1
  •   LiraNuna    16 年前

    SQL Server没有任何数据类型能够在一行的列中存储超过2 GB的数据。

    如果您有足够的磁盘空间,数据库(而不是速成版)可以存储超过2GB的数据,但行中一列数据量的限制适用。

        3
  •  1
  •   JRL    16 年前

    您需要做的只是将日志文件拆分为2-3个文件,您仍然可以使用所使用的导入查询。

    例如,您可以用editpad打开文件(不要用notepad++打开文件,因为文件太大,而editpad会立即打开),然后只剪切和粘贴几个文件(使它们成为正确的xml,复制头和结束标记)。

    推荐文章