Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 生成插入脚本(如果不存在)_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql 生成插入脚本(如果不存在)

Sql 生成插入脚本(如果不存在),sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我在数据库中有一个主表 示例菜单表 +-----------+-----------+-------------+---------+------------------------+ | Id | Key | Display Text| ParentId| CreatedOn +-----------+-----------+-------------+---------+------------------------+ | 1 | Home

我在数据库中有一个主表

示例菜单表

+-----------+-----------+-------------+---------+------------------------+
| Id        | Key       | Display Text| ParentId| CreatedOn
+-----------+-----------+-------------+---------+------------------------+
| 1         | Home      | Home        | NULL    |2014-01-14 21:17:37.387 |
| 2         | About     | About Us    | NULL    |2014-01-14 21:17:37.387 |
| 3         | Contact   | Contact Us  | NULL    |2014-01-14 21:17:37.387 |
+-----------+-----------+------+------+---------+------------------------+
我曾经为每条记录生成如下所示的主数据脚本

IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=1 AND Key='Home')
BEGIN
SET IDENTITY_INSERT [dbo].[Menu] ON

INSERT INTO [dbo].[Menu]
           (Id
           ,[Key]
           ,[DisplayText]
           ,[ParentId]
           ,[CreatedOn])
     VALUES
           (1
           ,'Home'
           ,'Home'
           ,NULL
           ,GETDATE()
           )
SET IDENTITY_INSERT [dbo].[Menu] OFF

END
GO
--对所有70条记录和其他主数据重复相同的手动记录创建工作(
10k行

但是,另一个数据库中的某些现有表
ApplicationMenu
具有相同的列,即数据类型。我们希望通过使用一些存储过程为我们自动生成下面的脚本

是否可以创建如下所示的过程

CREATE PROCEDURE spGenerateInsertScripts
(
  @SourceTableName VARCHAR(100),
  @ExistsWhereClauseTemplate NVARCHAR(1000),
  @TargetTableName VARCHAR(100)
)
BEGIN

 -- In some loop create those above insert statements
END
  exec spGenerateInsertScripts 'ApplicationMenu'
                               , 'WHERE Id={Id} AND Key={Key}'
                               , 'Menu'
我们希望执行如下操作

CREATE PROCEDURE spGenerateInsertScripts
(
  @SourceTableName VARCHAR(100),
  @ExistsWhereClauseTemplate NVARCHAR(1000),
  @TargetTableName VARCHAR(100)
)
BEGIN

 -- In some loop create those above insert statements
END
  exec spGenerateInsertScripts 'ApplicationMenu'
                               , 'WHERE Id={Id} AND Key={Key}'
                               , 'Menu'
在这里,{Id}&{Key}将从现有表的每一行中读取并替换

这实际上会减少我们大量的体力劳动

注意:

我们无法使用SQL server插入脚本生成工具,因为我们希望检查数据是否存在,并且需要保留用户使用我们的应用程序添加的记录

需要生成一个插入脚本,以便我们可以在将来运行,即使ApplicationTable不可用

是否可以编写这样一个过程,根据存在性从其他表生成插入脚本?就像sql server
生成脚本如何通过查看信息\u SCHEMA
表来创建表一样,这与我期望的方式相同


该过程的最终输出类似于
PRINT@insert\u Sql\u Statements

假设我正确理解了您的问题,您的建议(where子句作为参数)听起来不太好,可能会导致大量其他问题(例如Sql注入、验证Sql字符串格式是否正确等)

这种使用链接服务器的方法怎么样

SET IDENTITY_INSERT [dbo].[Menu] ON
GO

INSERT INTO [dbo].[Menu] ([Id],[Key],[DisplayText],[ParentId],[CreatedOn])
SELECT a.Id, a.Key, a.Key, NULL, GETDATE()
FROM [ApplicationMenu_Instance].[ApplicationMenu_Database].[dbo].[ApplicationMenu] AS a
WHERE NOT EXISTS (
    SELECT 1
    FROM [dbo].[Menu] AS m
    WHERE m.Id = a.Id
        AND m.Key = a.Key
)

SET IDENTITY_INSERT [dbo].[Menu] OFF
GO
更新: 既然要返回插入脚本,那么动态SQL如何:

CREATE PROCEDURE spGenerateInsertScripts
(
    @SourceTable VARCHAR(100),
    @TargetTable VARCHAR(100)
)  
BEGIN
    DECLARE @SQL NVARCHAR(MAX) = '
    SET IDENTITY_INSERT [dbo].[Menu] ON
    GO

    INSERT INTO [dbo].[' + @TargetTable + '] ([Id],[Key],[DisplayText],[ParentId],[CreatedOn])
    SELECT a.Id, a.Key, a.Key, NULL, GETDATE()
    FROM ' + @SourceTable + '  AS a
    WHERE NOT EXISTS (
        SELECT 1
        FROM [dbo].[' + @TargetTable + '] AS m
        WHERE m.Id = a.Id
            AND m.Key = a.Key
    )

    SET IDENTITY_INSERT [dbo].[Menu] OFF
    GO
   ';

    SELECT @SQL;
END

您的数据

DECLARE @Table TABLE(Id INT, [Key] VARCHAR(30),[Display Text] VARCHAR(30), ParentId INT,  CreatedOn DATETIME)
INSERT INTO @Table VALUES 
(1,'Home'   ,'Home'      ,NULL, '2014-01-14 21:17:37.387'), 
(2,'About'  ,'About Us'  ,NULL, '2014-01-14 21:17:37.387'),
(3,'Contact','Contact Us',NULL, '2014-01-14 21:17:37.387')
查询以创建脚本

SELECT  N'IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id='+  CAST(Id AS NVARCHAR(10)) 
       + ' AND Key='''+ CAST([Key] AS NVARCHAR(1000)) +''')' + CHAR(10) 
        + N'BEGIN ' + CHAR(10) + '
        SET IDENTITY_INSERT [dbo].[Menu] ON ' + CHAR(10) + ' 

        INSERT INTO [dbo].[Menu]      ' + CHAR(10) + ' 
                   (Id    ' + CHAR(10) + ' 
                   ,[Key] ' + CHAR(10) + ' 
                   ,[DisplayText]' + CHAR(10) + ' 
                   ,[ParentId]' + CHAR(10) + ' 
                   ,[CreatedOn])' + CHAR(10) + ' 
             VALUES' + CHAR(10) + ' 
                   ( '  + ISNULL(CAST(Id AS NVARCHAR(10)), 'NULL') + ' ' + CHAR(10) + ' 
                   ,''' + ISNULL(CAST([Key] AS NVARCHAR(1000)), 'NULL') +''' ' + CHAR(10) + ' 
                   ,''' + ISNULL(CAST([Display Text] AS NVARCHAR(1000)), 'NULL')  + ''' ' + CHAR(10) + ' 
                   ,' +  ISNULL(CAST(ParentId AS NVARCHAR(10)), 'NULL')  + ' ' + CHAR(10) + ' 
                   ,GETDATE() ' + CHAR(10) + ' 
                   ) ' + CHAR(10) + ' 
        SET IDENTITY_INSERT [dbo].[Menu] OFF ' + CHAR(10) + ' 
        END ' + CHAR(10) + ' 
        GO ' + CHAR(10) + ' '+ CHAR(10)
FROM @Table
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                                                                                                                                                          (No column name)                                                                                                                                                                                                                          ║
╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=1 AND Key='Home') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 1            ,'Home'            ,'Home'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO                 ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=2 AND Key='About') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 2            ,'About'            ,'About Us'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO           ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=3 AND Key='Contact') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 3            ,'Contact'            ,'Contact Us'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO     ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
生成的脚本

SELECT  N'IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id='+  CAST(Id AS NVARCHAR(10)) 
       + ' AND Key='''+ CAST([Key] AS NVARCHAR(1000)) +''')' + CHAR(10) 
        + N'BEGIN ' + CHAR(10) + '
        SET IDENTITY_INSERT [dbo].[Menu] ON ' + CHAR(10) + ' 

        INSERT INTO [dbo].[Menu]      ' + CHAR(10) + ' 
                   (Id    ' + CHAR(10) + ' 
                   ,[Key] ' + CHAR(10) + ' 
                   ,[DisplayText]' + CHAR(10) + ' 
                   ,[ParentId]' + CHAR(10) + ' 
                   ,[CreatedOn])' + CHAR(10) + ' 
             VALUES' + CHAR(10) + ' 
                   ( '  + ISNULL(CAST(Id AS NVARCHAR(10)), 'NULL') + ' ' + CHAR(10) + ' 
                   ,''' + ISNULL(CAST([Key] AS NVARCHAR(1000)), 'NULL') +''' ' + CHAR(10) + ' 
                   ,''' + ISNULL(CAST([Display Text] AS NVARCHAR(1000)), 'NULL')  + ''' ' + CHAR(10) + ' 
                   ,' +  ISNULL(CAST(ParentId AS NVARCHAR(10)), 'NULL')  + ' ' + CHAR(10) + ' 
                   ,GETDATE() ' + CHAR(10) + ' 
                   ) ' + CHAR(10) + ' 
        SET IDENTITY_INSERT [dbo].[Menu] OFF ' + CHAR(10) + ' 
        END ' + CHAR(10) + ' 
        GO ' + CHAR(10) + ' '+ CHAR(10)
FROM @Table
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                                                                                                                                                          (No column name)                                                                                                                                                                                                                          ║
╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=1 AND Key='Home') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 1            ,'Home'            ,'Home'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO                 ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=2 AND Key='About') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 2            ,'About'            ,'About Us'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO           ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=3 AND Key='Contact') BEGIN      SET IDENTITY_INSERT [dbo].[Menu] ON         INSERT INTO [dbo].[Menu]                 (Id               ,[Key]            ,[DisplayText]           ,[ParentId]           ,[CreatedOn])        VALUES           ( 3            ,'Contact'            ,'Contact Us'            ,NULL            ,GETDATE()            )       SET IDENTITY_INSERT [dbo].[Menu] OFF       END       GO     ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
注意


我在
网格中得到了结果,但您可以将结果导出到文件或文本中,并在需要执行时将其复制粘贴到查询窗口中

您可以使用SQL语句生成所需的insert语句。然后,您可以将输出复制并粘贴到您想要执行查询的任何位置

它不是一个通用的解决方案,可以创建一个脚本,从另一个表向一个表中生成insert语句,但它将大大减少特定情况下所需的手动工作。您可以配置目标表的名称,但列名和值以及从中检索数据的表的名称是硬编码的

它假定输入的目标表与从中检索数据的表具有相同的模式

DECLARE @TARGET_TABLE AS VARCHAR(100) = '[dbo].[Menu]'

SELECT Script
FROM
(
    SELECT Id, [Key], 0 AS [Order], 
        'IF NOT EXISTS(SELECT 1 FROM ' + @TARGET_TABLE + 
        ' WHERE Id=' + CONVERT(varchar(100), Id) + 
        ' AND Key=''' + [Key] + ''')' AS Script
    FROM ApplicationMenu
    UNION
    SELECT Id, [Key], 1 AS [Order], 'BEGIN' AS Script
    FROM ApplicationMenu
    UNION
    SELECT Id, [Key], 2, 'SET IDENTITY_INSERT ' + @TARGET_TABLE + ' ON'
    FROM ApplicationMenu
    UNION
    SELECT Id, [Key], 3, 
        'INSERT INTO ' + @TARGET_TABLE + 
        ' VALUES(' + 
        CONVERT(varchar(11), Id) + ', ''' + 
        [Key] + ''', ''' + 
        [DisplayText] + ''', ' + 
        ISNULL(CONVERT(varchar(11), ParentId), 'NULL') + 
        ', GETDATE())'
    FROM ApplicationMenu
    UNION
    SELECT Id, [Key], 4, 'SET IDENTITY_INSERT ' + @TARGET_TABLE + ' OFF'
    FROM ApplicationMenu
    UNION
    SELECT Id, [Key], 5, 'END'
    FROM ApplicationMenu
) AS ScriptInfo
ORDER BY Id, [Key], [Order]
老实说,脚本看起来有点痛苦,但它完成了任务

如果您真的想要一个通用的问题解决方案,那么您可能会更幸运地用某种编程语言(如C#)实现它。在C#中实现它的好处是,您可以将库导入SQL server并像调用存储过程一样调用它(我想,我以前从未做过这种事情)


此外,还有一些工具可以为您生成此类脚本。如果我没记错的话,RedGate SQL数据比较将非常容易地完成这类工作。可能还有其他行。

因此您希望使用ApplicationMenu表(在其他数据库中)在菜单数据库中创建行(如果这些行还不存在)。使用ApplicationMenu中的Id和Key列?为什么不创建一个存储过程,它接受表值参数并将值传递给存储过程,然后返回添加到目标表中的值呢@乌米尔,是的。这两个表具有相同的列名和数据类型。我想将所有ApplicationMenu导入到我的菜单表中,但前提是它们不是exists@M.Ali,我需要一个插入脚本,以便以后可以随时运行,即使ApplicationMenu表不可用。但我需要它作为
文本脚本
,以便即使ApplicationMenu不可用,我也可以随时运行该脚本。我想在ApplicationMenu可用时生成脚本文本,之后我想随时重新运行。对不起,我不太明白。为什么不能用上面的代码创建一个sp,然后在需要时执行它?是否需要它,以便可以决定源应用程序菜单表的位置(通过传递参数)?我看起来类似于使用sql server生成脚本工具生成存储过程脚本。在数据库中不存在表时,可以选择创建表。因此,通过检查
INFORMATION\u SCHEMA
table,它将自动为我们生成一个表脚本。同样,我希望使用value语句,而不是
从ApplicationMenu
中选择a.Id、a.Key、a.Key、NULL、GETDATE()。请检查我的问题。到现在为止,我正在逐一插入。我想要一些助手程序通过读取另一个表来生成这些记录。Awwww,对于基本相同的答案,要慢24分钟+谢谢你,先生,先到那儿。