0

我有一个很大的 SQL 文本文件,其中有很多用于创建表、列等的 SQL 命令。

示例行:

IF NOT EXISTS ( SELECT * FROM dbo.sysobjects WHERE id = object_id(N'xcal_views') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) 
   CREATE TABLE xcal_views (lid INT NOT NULL);
GO

IF NOT EXISTS ( SELECT * FROM dbo.sysobjects WHERE id = object_id(N'xcal_views_actors') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) 
   CREATE TABLE xcal_views_actors (lid INT NOT NULL);
GO

IF NOT EXISTS ( SELECT * FROM dbo.syscolumns, dbo.sysobjects WHERE [dbo].[syscolumns].[name] = 'xlactor' AND [dbo].[sysobjects].[id] = [dbo].[syscolumns].[id] AND [dbo].[sysobjects].[id] = object_id(N'xcal_views_actors') AND OBJECTPROPERTY([dbo].[sysobjects].[id], N'IsUserTable') = 1 ) 
   ALTER TABLE [dbo].[xcal_views_actors] ADD xlactor INT NULL;
GO

IF NOT EXISTS ( SELECT * FROM dbo.syscolumns, dbo.sysobjects WHERE [dbo].[syscolumns].[name] = 'lparentid' AND [dbo].[sysobjects].[id] = [dbo].[syscolumns].[id] AND [dbo].[sysobjects].[id] = object_id(N'xcal_views_actors') AND OBJECTPROPERTY([dbo].[sysobjects].[id], N'IsUserTable') = 1 ) 
   ALTER TABLE [dbo].[xcal_views_actors] ADD lparentid INT NULL;
GO

IF NOT EXISTS ( SELECT * FROM dbo.sysobjects WHERE parent_obj = (SELECT id FROM dbo.sysobjects WHERE id = object_id(N'xcal_views_actors') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) AND OBJECTPROPERTY(id, N'IsPrimaryKey') = 1) 
   ALTER TABLE [dbo].[xcal_views_actors] 
   ADD CONSTRAINT [CT_00000501] PRIMARY KEY CLUSTERED (lid ASC);
GO

IF NOT EXISTS ( SELECT * FROM [sys].[indexes] i INNER JOIN [sys].[objects] o ON o.object_id = i.object_id AND o.name = 'xcal_views_actors' WHERE i.name = 'parent_id' ) 
   CREATE INDEX parent_id ON xcal_views_actors (lparentid ASC)
GO

在每个命令之间,我有一个GO额外的行来分隔命令。

patch.sql如果我从 SQL Server Management Studio运行整个文件,所有命令都会执行并且工作正常。

在 .NET 中,我阅读了整个文本文件,然后用“GO”拆分它们并对数据库执行每个 SQL 命令。

现在奇怪的是:一些命令没有被执行。我不知道为什么。

这是完成这项工作的方法:

private static void patchDatabase(string connection, string sqlfile)
{
  var defaultEncoding = Encoding.Default;
  using (FileStream fs = File.OpenRead(sqlfile))
  {
    defaultEncoding = TextFileEncodingDetector.DetectTextFileEncoding(fs, defaultEncoding, 1024);
  }
  //Console.WriteLine(string.Format("File {0} using encoding: {1}",sqlfile, defaultEncoding));

  var dbPatch = new StreamReader(sqlfile, defaultEncoding);
  string sqlPatch = dbPatch.ReadToEnd();
  dbPatch.Close();
  string[] stringSeparators = new[] {"GO"};
  string[] sqlPatches = sqlPatch.Split(stringSeparators, StringSplitOptions.None);

  if (connection != null && sqlPatch.Length > 0)
  {
    Console.WriteLine(string.Format("Executing {0} statements from {1}", sqlPatches.Length, sqlfile));

    using (var cnn = new SqlConnection(connection))
    {
      cnn.Open();
      foreach (var sql in sqlPatches)
      {
        if (String.IsNullOrEmpty(sql))
          continue; // Not a real sql statement, use next

        using (var cmd = new SqlCommand(sql, cnn))
        {
          try
          {
            cmd.CommandTimeout = 120;
            cmd.ExecuteNonQuery();
            //int results = cmd.ExecuteNonQuery();
            //if (results < 1)
            //  Console.WriteLine(String.Format("Failed:\nResult: {0}\n{1}",results, sql));
          }
          catch (Exception ex)
          {
            Console.WriteLine("Execution error!\n\n" + sql + "\n\n\n" + ex);
          }
        }
      }
      cnn.Close();
    }

  }
}

它看起来像我的功能飞溅......

我当前的文本文件大约有 6.000 多行。

知道我做错了什么吗?

4

1 回答 1

0

看起来这根本不是编码问题。

实际上我产生了以下情况:

  • 我有一个数据库“test_db”

  • 我创建了一个用户“test_db_user”并使他成为 db_owner 他通常添加到 sql server 中“安全 - 角色”,objekt“test_db”作为角色 db_owner 他还被添加为数据库“test_db”中的用户 - 安全 - 用户。

  • 现在它来了:经过一些测试,我再次恢复了数据库。该用户不再列在“test_db”-安全-用户中,但通常仍配置为 db_owner。

然后连接以某种方式工作,但它始终没有完全访问数据库。无法真正知道出了什么问题。在管理工作室中,我曾经使用管理员帐户来启动 sql 批处理,这就是它一直在那里工作的原因。

所以解决方案:确保安全设置 100% 正确,然后它可以工作:S

另一个问题是我的愚蠢:S!!! 我有一些没有 dbo 的创建表语句。表之前的模式,因此不同的用户为表创建了不同的模式名称。

感谢大家的反馈。

于 2012-05-25T18:51:10.537 回答