如何动态创建视图?

时间:2015-03-01 20:56:56

标签: c# sql-server regex string

背景

我有一个网站,显示客户端独有的数据。添加新客户端时,站点需要创建视图。每个客户都是唯一的,并且具有不同的识别信息。例如ID号和前缀。

每次添加新客户端时,都会使用标准视图集手动创建一组新视图,每次只更改客户端的唯一信息。这通常使用SQL Server Management Studio(SSMS)中的查找和替换

来完成

到目前为止我有什么?

我创建了一个Winform应用程序,它捕获唯一信息并将它们放入变量中。然后将这些变量放入用于创建视图的标准脚本中。

问题

我的脚本包含SMSS语句不是本机SQL语句,这会导致我的程序出错并中断其对数据库的提交。

有问题的陈述是用于通过SMSS运行批次的GO关键字。

到目前为止我尝试了什么?

我使用String Literal封装了整个脚本,并在GO语句之前和之后插入了一个新行,如另一个问题所示。但它似乎没有用。

我现在在尝试什么?

使用REGEX在每个“GO'”中分割脚本。发生。这也不起作用。

问题

是否有更好的解决方案来解决此问题或修复我的解决方案?

代码

 string connectionString = fmDbSelect();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {

                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = connection;
                    connection.Open();
                    var scripts = Regex.Split(sql, @"^\w+GO$", RegexOptions.Multiline);
                    foreach (var splitScript in scripts)
                    {
                        command.CommandText = splitScript;
                        command.ExecuteNonQuery();

                    }


                }
            }

错误消息

  

{&#34;语法附近&#39; ANSI_NULLS&#39;。\ r \ n附近的语法不正确   &#39; QUOTED_IDENTIFIER&#39;。\ r \ n&#39;。&#39;。\ r \ n之间的语法不正确\ n \ n \ n语法不正确   接近&#39; ANSI_NULLS&#39;。\ r \ n附近的语法不正确   &#39; QUOTED_IDENTIFIER&#39;。\ r \ n <&#39;。&#39;。\ r \ n&#39;创建视图&#39;附近的语法不正确   必须是查询批处理中的第一个语句。\ r \ n语法不正确   &#39;)&#39;。\ r \ n <&#39;附近的语法不正确&#39;。\ r \ n附近的语法不正确   &#39;)&#39;。\ r \ n&#39; ANSI_NULLS&#39;。\ r \ n附近的语法不正确   &#39; ANSI_NULLS&#39;。\ r \ n在关键字&#39; AS&#39;。\ r \ n附近的语法不正确   关键字附近的语法&#39; AS&#39;。\ r \ n关键字附近的语法不正确   &#39; AS&#39;。\ r \ n在关键字&#39; AS&#39;。\ r \ n附近的语法不正确\ n \ n语法不正确   靠近关键字&#39; AS&#39;。\ r \ n关键字附近的语法不正确   &#39; AS&#39;。\ r \ n

我的剧本

  

/ ******对象:查看[dbo]。[TIDEreportEmails]脚本日期:   23/02/2015 12:43:36 ****** / SET ANSI_NULLS ON GO

     

设置QUOTED_IDENTIFIER

     

创建视图[dbo]。[TIDEreportEmails] AS SELECT EmailID,   EmailContent,EmailSubject,EmailTo,EmailFrom,UserID,ObjectValueID,   EmailSent,EmailCreated,EmailRead,EmailFromName,EmailType,   EmailFailed,                         电子邮件发送时为空但未读取的情况&#39; ELSE&#39;阅读&#39; END作为电子邮件地址来自DEReportingClient2DB.dbo.Emails   AS Emails_1 WHERE(UserID IN                             (SELECT UserID                               来自DEReportingClient2DB.dbo.Users                               WHERE(ClientID = 195)))

     

GO

     

/ ******对象:查看[dbo]。[TIDEunreadEmails]脚本日期:   23/02/2015 12:43:36 ****** / SET ANSI_NULLS ON GO

     

设置QUOTED_IDENTIFIER

     

创建视图[dbo]。[TIDEunreadEmails] AS SELECT COUNT(*)AS   UnreadEmails,UserID FROM dbo.TIDEreportEmails WHERE
  (EmailRead IS NULL)GROUP BY UserID

3 个答案:

答案 0 :(得分:2)

您的RegEx无法正确分割线条;您可以使用以下语句之一来拆分脚本。

  1. sql.Split(new string [] {&#34; GO&#34;}。
  2. Regex.Split(sql,@&#34; \ bGO \ b&#34;,RegexOptions.Multiline);
  3. 以下是代码段

          string connectionString = fmDbSelect();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
    
                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = connection;
                    connection.Open();
                    var scripts = Regex.Split(sql, @"\bGO\b", RegexOptions.Multiline);
                    //var scripts = sql.Split(new string[] { "GO" }, StringSplitOptions.None);
                    foreach (var splitScript in scripts)
                    {
                        command.CommandText = splitScript;
                        command.ExecuteNonQuery();
    
                    }
    
    
                }
            }
    

答案 1 :(得分:1)

删除GO语句。

SSMS使用GO来发送单独的批次&#34;到SQL Server ......它只不过是一个分隔符。大多数那些你不需要的人。

如果某些东西必须是批处理中的第一件事(比如CREATE VIEW语句),只需在一个批处理中发送所有内容,然后在单独的语句中,将完整的CREATE VIEW语句作为代码中的单独步骤发送

您可以而且应该使用相同的连接对象,只需发送一个命令,然后发送一个不同的命令,每个批次一个。并且没有必要将&#34; SET&#34; GO的陈述。您可以将所有SET语句放在一起......并且您只需在连接上执行一次。所以...使用一个命令发送SET语句。然后是一个命令来自己发送每个CREATE VIEW语句。

答案 2 :(得分:1)

如果操作正确,

GO 上的拆分会有效。你只是错误地分裂。使用调试器检查您要执行的操作。它显然会被打破。

确保您没有将GO发送到服务器。

你的剧本中的换行符似乎搞砸了。也许这只是在这里获得剧本的一种神器。