2017-01-09 29 views
6

Jak wygenerować skrypt DDL (z kluczami obcymi, indeksy itp.) Wszystkich tabel z bazy danych SQL Server za pomocą SQL (wybierz/procedura przechowywana/itp.)? potrzebuję wszystkiego oprócz danych.wygenerować skrypt DDL z bazy danych SQL Server

I nie można używać Sql Server Management Studio, ponieważ chcę go używać w skrypcie node.js, który będzie działać na Linuksie!

+4

Jest to prawie niemożliwe do zrobienia dla całej bazy danych ze skryptem, który faktycznie działa. Mogą istnieć specjalne tabele zamówień, które należy utworzyć ze względu na ich klucze obce. Dlaczego nie możesz po prostu użyć SSMS do wygenerowania skryptu, a następnie uruchomić go z dowolnego miejsca? Jak często zamierzasz tworzyć całą bazę danych dynamicznie w oparciu o zawartość istniejącej bazy danych? Jeśli cokolwiek, możesz stworzyć czystą i pustą kopię bazy danych i po prostu przywrócić ją do jakiejkolwiek nazwy. Lub skopiuj inną bazę danych i przygotuj skrypt do skasowania/usunięcia wszystkich danych w celu utworzenia czystej bazy danych. –

+0

Istnieją trzy obsługiwane sposoby, aby to zrobić od firmy Microsoft. Możesz to zrobić z SSMS (Management Studio), SMO (https://msdn.microsoft.com/en-us/library/ms162557.aspx) lub z Powershell. – RBarryYoung

+1

@SeanLange będę kopiować tabele serval razy dziennie –

Odpowiedz

2

dla tabel: (można pracować dalej)

DECLARE @C VARCHAR(200) 
DECLARE C CURSOR FOR 
SELECT 'EXEC [DBO].[SP_GETDDL] '''+NAME+'''' FROM SYS.TABLES 
OPEN C 
FETCH NEXT FROM C INTO @C 
WHILE @@FETCH_STATUS=0 
BEGIN 
EXEC (@C) 
FETCH NEXT FROM C INTO @C 
END 
CLOSE C 
DEALLOCATE C 

Procedura jest następująca:

CREATE PROCEDURE [dbo].[Sp_getddl] @TBL VARCHAR(255) 
AS 
    BEGIN 
     SET nocount ON 

     DECLARE @TBLNAME   VARCHAR(200), 
       @SCHEMANAME   VARCHAR(255), 
       @STRINGLEN   INT, 
       @TABLE_ID   INT, 
       @FINALSQL   VARCHAR(max), 
       @CONSTRAINTSQLS  VARCHAR(max), 
       @CHECKCONSTSQLS  VARCHAR(max), 
       @RULESCONSTSQLS  VARCHAR(max), 
       @FKSQLS    VARCHAR(max), 
       @TRIGGERSTATEMENT VARCHAR(max), 
       @EXTENDEDPROPERTIES VARCHAR(max), 
       @INDEXSQLS   VARCHAR(max), 
       @vbCrLf    CHAR(2) 

     SET @vbCrLf = Char(13) + Char(10) 

     SELECT @SCHEMANAME = Isnull(Parsename(@TBL, 2), 'dbo'), 
      @TBLNAME = Parsename(@TBL, 1) 

     SELECT @TABLE_ID = [object_id] 
     FROM sys.objects 
     WHERE [type] = 'U' 
      AND [name] <> 'dtproperties' 
      AND [name] = @TBLNAME 
      AND [schema_id] = Schema_id(@SCHEMANAME); 

     IF Isnull(@TABLE_ID, 0) = 0 
     BEGIN 
      SET @FINALSQL = 'Table object [' + @SCHEMANAME + '].[' 
          + Upper(@TBLNAME) 
          + '] does not exist in Database [' 
          + Db_name() + ']' 

      SELECT @FINALSQL; 

      RETURN 0 
     END 

     SELECT @FINALSQL = 'CREATE TABLE [' + @SCHEMANAME + '].[' 
         + Upper(@TBLNAME) + '] (' 

     SELECT @TABLE_ID = Object_id(@TBLNAME) 

     SELECT @STRINGLEN = Max(Len(sys.columns.[name])) + 1 
     FROM sys.objects 
      INNER JOIN sys.columns 
        ON sys.objects.[object_id] = sys.columns.[object_id] 
         AND sys.objects.[object_id] = @TABLE_ID; 

     SELECT @FINALSQL = @FINALSQL + CASE WHEN sys.columns.[is_computed] = 1 
         THEN 
         @vbCrLf + 
           '[' + Upper( 
           sys.columns.[name]) + '] ' + Space(@STRINGLEN - 
           Len(sys.columns.[name])) + 'AS ' + 
           Isnull(CALC.definition, '') ELSE 
           @vbCrLf + '[' + Upper(sys.columns.[name]) + '] ' 
         + 
         Space( 
           @STRINGLEN - Len(sys.columns.[name])) + 
           Upper(Type_name(sys.columns.[user_type_id])) + 
         CASE 
         WHEN 
           Type_name(sys.columns.[user_type_id]) IN ( 
         'decimal', 
           'numeric') THEN '(' + CONVERT( 
           VARCHAR, sys.columns.[precision]) + ',' + 
         CONVERT( 
         VARCHAR, 
           sys.columns.[scale]) + ') ' + Space(6 - Len( 
         CONVERT( 
         VARCHAR, 
           sys.columns.[precision]) + ',' + 
           CONVERT(VARCHAR, sys.columns.[scale]))) + Space( 
         2) 
         -- + SPACE(16 - LEN(TYPE_NAME(sys.columns.[user_type_id]))) 
         + CASE WHEN Columnproperty (@TABLE_ID, 
         sys.columns.[name], 
           'IsIdentity') = 0 THEN '    ' ELSE 
         ' IDENTITY(' + 
           CONVERT(VARCHAR, Isnull(Ident_seed(@TBLNAME), 1) 
         ) 
         + 
         ',' + 
           CONVERT(VARCHAR, Isnull(Ident_incr(@TBLNAME), 1) 
         ) 
         + 
         ')' END 
           + CASE WHEN sys.columns.[is_nullable] = 0 THEN 
         ' NOT NULL' 
           ELSE '  NULL' END WHEN 
           Type_name(sys.columns.[user_type_id]) IN ( 
         'float', 
         'real') 
           THEN CASE WHEN 
           sys.columns.[precision] = 53 THEN Space(11 - 
           Len(CONVERT(VARCHAR, sys.columns.[precision]))) 
         + 
         Space(7) + 
           Space(16 - 
           Len(Type_name(sys.columns.[user_type_id]))) + 
         CASE 
         WHEN 
           sys.columns.[is_nullable] = 0 THEN 
           ' NOT NULL' ELSE '  NULL' END ELSE '(' + 
         CONVERT( 
         VARCHAR, 
           sys.columns.[precision]) + ') ' + Space(6 - Len( 
         CONVERT( 
           VARCHAR, sys.columns.[precision]))) + Space(7) + 
         Space 
         (16 
           - Len(Type_name(sys.columns.[user_type_id]))) + 
         CASE 
         WHEN 
           sys.columns.[is_nullable] = 0 THEN ' NOT NULL' 
         ELSE 
           '  NULL' END 
           END WHEN Type_name(sys.columns.[user_type_id]) 
         IN 
         ( 
         'char', 
           'varchar') THEN CASE WHEN 
         sys.columns.[max_length] 
         = 
         -1 THEN 
           '(max)' + Space(6 - 
           Len(CONVERT(VARCHAR, sys.columns.[max_length]))) 
         + 
         Space(7) + 
           Space(16 - 
           Len(Type_name(sys.columns.[user_type_id]))) + 
         CASE 
         WHEN 
           sys.columns.collation_name IS NULL THEN '' 
           ELSE ' COLLATE ' + sys.columns.collation_name 
         END 
         + 
         CASE WHEN 
           sys.columns.[is_nullable] = 0 THEN ' NOT NULL' 
         ELSE 
           '  NULL' END ELSE '(' + 
           CONVERT(VARCHAR, sys.columns.[max_length]) + 
         ') ' 
         + 
         Space(6 - 
           Len(CONVERT(VARCHAR, sys.columns.[max_length]))) 
         + 
         Space(7) + 
           Space(16 - 
           Len(Type_name(sys.columns.[user_type_id]))) + 
         CASE 
         WHEN 
           sys.columns.collation_name IS NULL THEN '' 
           ELSE ' COLLATE ' + sys.columns.collation_name 
         END 
         + 
         CASE WHEN 
           sys.columns.[is_nullable] = 0 THEN ' NOT NULL' 
         ELSE 
           '  NULL' END END WHEN 
           Type_name(sys.columns.[user_type_id]) IN ( 
         'nchar', 
         'nvarchar' 
           ) THEN CASE WHEN 
           sys.columns.[max_length] = -1 THEN '(max)' + 
         Space 
         (6 - 
Len(CONVERT(VARCHAR, (sys.columns.[max_length])))) 
+ 
Space(7) 
+ Space(16 - Len(Type_name( 
sys.columns.[user_type_id]))) + CASE WHEN 
sys.columns.collation_name IS NULL THEN '' ELSE 
' COLLATE ' + 
sys.columns.collation_name END + CASE WHEN 
sys.columns.[is_nullable] = 0 THEN 
' NOT NULL' ELSE '  NULL' END ELSE '(' + 
CONVERT( 
VARCHAR, 
(sys.columns.[max_length])) + ') ' + Space(6 - Len 
( 
CONVERT( 
VARCHAR, (sys.columns.[max_length])))) + Space(7) 
+ 
Space(16 
- Len(Type_name(sys.columns.[user_type_id]))) + 
CASE 
WHEN 
sys.columns.collation_name IS NOT NULL THEN '' 
ELSE 
' COLLATE ' + 
sys.columns.collation_name END + CASE WHEN 
sys.columns.[is_nullable] 
= 0 THEN ' NOT NULL' ELSE '  NULL' END END WHEN 
Type_name( 
sys.columns.[user_type_id]) IN ('datetime', 
'money', 
'text', 
'image') THEN Space(18 - 
Len(Type_name(sys.columns.[user_type_id]))) + 
'    ' + CASE WHEN 
sys.columns.[is_nullable] = 0 THEN ' NOT NULL' 
ELSE 
'  NULL' END ELSE Space(16 
- Len(Type_name(sys.columns.[user_type_id]))) + 
CASE 
WHEN 
Columnproperty (@TABLE_ID, sys.columns.[name], 
'IsIdentity' 
) = 0 THEN '    ' ELSE ' IDENTITY(' + 
CONVERT( 
VARCHAR, Isnull(Ident_seed(@TBLNAME), 1)) + ',' + 
CONVERT( 
VARCHAR, Isnull(Ident_incr(@TBLNAME), 1)) + ')' 
END + 
Space( 
2) + CASE WHEN sys.columns.[is_nullable] = 0 THEN 
' NOT NULL' 
ELSE '  NULL' END END + CASE WHEN 
sys.columns.[default_object_id] = 0 THEN '' 
--ELSE ' DEFAULT ' + ISNULL(def.[definition] ,'')  
--optional section in case NAMED default cosntraints are needed: 
ELSE @vbCrLf + 'CONSTRAINT [' + def.NAME + '] DEFAULT ' + 
Isnull(def.[definition], '') 
--i thought it needed to be handled differently! NOT!   
END --CASE cdefault  
END --iscomputed   
+ ',' 
FROM sys.columns 
LEFT OUTER JOIN sys.default_constraints DEF 
ON sys.columns.[default_object_id] = DEF.[object_id] 
LEFT OUTER JOIN sys.computed_columns CALC 
ON sys.columns.[object_id] = CALC.[object_id] 
AND sys.columns.[column_id] = CALC.[column_id] 
WHERE sys.columns.[object_id] = @TABLE_ID 
ORDER BY sys.columns.[column_id] 

SELECT @STRINGLEN = Max(Len([name])) + 1 
FROM sys.objects 

DECLARE @Results TABLE 
( 
[schema_id]    INT, 
[schema_name]   VARCHAR(255), 
[object_id]    INT, 
[object_name]   VARCHAR(255), 
[index_id]    INT, 
[index_name]   VARCHAR(255), 
[rows]     INT, 
[sizemb]    DECIMAL(19, 3), 
[indexdepth]   INT, 
[type]     INT, 
[type_desc]    VARCHAR(30), 
[fill_factor]   INT, 
[is_unique]    INT, 
[is_primary_key]  INT, 
[is_unique_constraint] INT, 
[index_columns_key]  VARCHAR(max), 
[index_columns_include] VARCHAR(max) 
) 

INSERT INTO @Results 
SELECT sys.schemas.schema_id, 
sys.schemas.[name] 
AS schema_name, 
sys.objects.[object_id], 
sys.objects.[name] 
AS object_name, 
sys.indexes.index_id, 
Isnull(sys.indexes.[name], '---') 
AS index_name, 
partitions.rows, 
partitions.sizemb, 
Indexproperty(sys.objects.[object_id], sys.indexes.[name], 
'IndexDepth') 
AS 
IndexDepth, 
sys.indexes.type, 
sys.indexes.type_desc, 
sys.indexes.fill_factor, 
sys.indexes.is_unique, 
sys.indexes.is_primary_key, 
sys.indexes.is_unique_constraint, 
Isnull(Index_Columns.index_columns_key, '---') 
AS index_columns_key, 
Isnull(Index_Columns.index_columns_include, '---') 
AS index_columns_include 
FROM sys.objects 
JOIN sys.schemas 
ON sys.objects.schema_id = sys.schemas.schema_id 
JOIN sys.indexes 
ON sys.objects.[object_id] = sys.indexes.[object_id] 
JOIN (SELECT [object_id], 
index_id, 
Sum(row_count)          AS 
Rows, 
CONVERT(NUMERIC(19, 3), CONVERT(NUMERIC(19, 3), Sum( 
        in_row_reserved_page_count 
        + lob_reserved_page_count 
        + 
        row_overflow_reserved_page_count 
       ))/
        CONVERT(NUMERIC(19, 3), 128)) AS 
SizeMB 
FROM sys.dm_db_partition_stats 
GROUP BY [object_id], 
index_id) AS partitions 
ON sys.indexes.[object_id] = partitions.[object_id] 
AND sys.indexes.index_id = partitions.index_id 
CROSS apply (SELECT LEFT(index_columns_key, 
Len(index_columns_key) - 1) 
AS 
index_columns_key 
, 
LEFT(index_columns_include, Len(index_columns_include) - 1) AS 
index_columns_include 
FROM (SELECT (SELECT sys.columns.[name] + ',' + ' ' 
FROM sys.index_columns 
JOIN sys.columns 
ON sys.index_columns.column_id = sys.columns.column_id 
AND sys.index_columns.[object_id] = 
sys.columns.[object_id] 
WHERE sys.index_columns.is_included_column = 0 
AND sys.indexes.[object_id] = 
sys.index_columns.[object_id] 
AND sys.indexes.index_id = sys.index_columns.index_id 
ORDER BY key_ordinal 
FOR xml path('')) AS index_columns_key, 
(SELECT sys.columns.[name] + ',' + ' ' 
FROM sys.index_columns 
JOIN sys.columns 
ON sys.index_columns.column_id = sys.columns.column_id 
AND sys.index_columns.[object_id] = 
sys.columns.[object_id] 
WHERE sys.index_columns.is_included_column = 1 
AND sys.indexes.[object_id] = 
sys.index_columns.[object_id] 
AND sys.indexes.index_id = sys.index_columns.index_id 
ORDER BY index_column_id 
FOR xml path('')) AS index_columns_include) AS Index_Columns) AS 
Index_Columns 
WHERE sys.schemas.[name] LIKE CASE 
     WHEN @SCHEMANAME = '' THEN 
     sys.schemas.[name] 
     ELSE @SCHEMANAME 
    END 
AND sys.objects.[name] LIKE CASE 
      WHEN @TBLNAME = '' THEN 
      sys.objects.[name] 
      ELSE @TBLNAME 
     END 
ORDER BY sys.schemas.[name], 
sys.objects.[name], 
sys.indexes.[name] 

[email protected] table has both PK,s Uniques and indexes in thme...pull them out for adding to funal results:  
SET @CONSTRAINTSQLS = '' 
SET @INDEXSQLS = '' 

SELECT @CONSTRAINTSQLS = @CONSTRAINTSQLS + CASE WHEN is_primary_key = 1 OR 
is_unique = 
     1 THEN @vbCrLf + 
     'CONSTRAINT [' + index_name + '] ' + Space 
( 
@STRINGLEN 
     - Len(index_name)) + CASE WHEN 
is_primary_key = 
1 THEN 
     ' PRIMARY KEY ' ELSE CASE WHEN is_unique = 1 
THEN 
     ' UNIQUE  ' ELSE '' END END + type_desc 
+ 
CASE WHEN 
     type_desc='NONCLUSTERED' THEN '' ELSE ' ' 
END 
+ ' (' 
     + index_columns_key + ')' + CASE WHEN 
     index_columns_include <> '---' THEN 
' INCLUDE (' 
+ 
     index_columns_include + ')' ELSE '' END + 
CASE 
WHEN 
     fill_factor <> 0 THEN ' WITH FILLFACTOR = ' 
+ 
CONVERT( 
     VARCHAR(30), fill_factor) ELSE '' END ELSE 
'' 
END + ',' 
FROM @RESULTS 
WHERE [type_desc] != 'HEAP' 
AND is_primary_key = 1 
OR is_unique = 1 
ORDER BY is_primary_key DESC, 
is_unique DESC 

SELECT @INDEXSQLS = @INDEXSQLS + CASE WHEN is_primary_key = 0 OR is_unique = 
0 THEN 
@vbCrLf + 
'CREATE INDEX [' + index_name + '] ' + Space( 
@STRINGLEN 
- Len(index_name)) + ' ON [' + [object_name] + 
']' + 
' (' + 
index_columns_key + ')' + CASE WHEN 
index_columns_include <> 
'---' THEN ' INCLUDE (' + index_columns_include + 
')' 
ELSE 
'' END + CASE WHEN fill_factor <> 0 THEN 
' WITH FILLFACTOR = ' + CONVERT(VARCHAR(30), 
fill_factor) 
ELSE '' END END 
FROM @RESULTS 
WHERE [type_desc] != 'HEAP' 
AND is_primary_key = 0 
AND is_unique = 0 
ORDER BY is_primary_key DESC, 
is_unique DESC 

IF @INDEXSQLS <> '' 
SET @INDEXSQLS = @vbCrLf + 'GO' + @vbCrLf + @INDEXSQLS 

SET @CHECKCONSTSQLS = '' 

SELECT @CHECKCONSTSQLS = @CHECKCONSTSQLS + @vbCrLf 
+ Isnull('CONSTRAINT [' + sys.objects.[name] + 
'] ' + 
Space( 
     @STRINGLEN - Len(sys.objects.[name])) + 
' CHECK ' + 
     Isnull(sys.check_constraints.definition, '') 
+ 
',', '') 
FROM sys.objects 
INNER JOIN sys.check_constraints 
ON sys.objects.[object_id] = 
sys.check_constraints.[object_id] 
WHERE sys.objects.type = 'C' 
AND sys.objects.parent_object_id = @TABLE_ID 

SET @FKSQLS = ''; 

SELECT @FKSQLS = @FKSQLS + @vbCrLf + 'CONSTRAINT [' 
+ Object_name(constid) + ']' 
+ Space(@STRINGLEN - Len(Object_name(constid))) 
+ ' FOREIGN KEY (' + Col_name(fkeyid, fkey) 
+ ') REFERENCES ' + Object_name(rkeyid) + '(' 
+ Col_name(rkeyid, rkey) + '),' 
FROM sysforeignkeys 
WHERE fkeyid = @TABLE_ID 

SET @RULESCONSTSQLS = '' 

SELECT @RULESCONSTSQLS = @RULESCONSTSQLS 
+ Isnull(@vbCrLf + 
'if not exists(SELECT [name] FROM sys.objects WHERE TYPE=''R'' AND schema_id = ' 
+ CONVERT(VARCHAR(30), sys.objects.schema_id) + 
' AND [name] = ''[' + 
Object_name(sys.columns.[rule_object_id]) + ']'')' + 
@vbCrLf + 
sys.sql_modules.definition + @vbCrLf + 'GO' + @vbCrLf + 
'EXEC sp_binderule [' 
+ sys.objects.[name] + '], ''[' + 
Object_name(sys.columns.[object_id]) + '].[' + 
sys.columns.[name] + 
']''' + @vbCrLf + 'GO', '') 
FROM sys.columns 
INNER JOIN sys.objects 
ON sys.objects.[object_id] = sys.columns.[object_id] 
INNER JOIN sys.sql_modules 
ON sys.columns.[rule_object_id] = sys.sql_modules.[object_id] 
WHERE sys.columns.[rule_object_id] <> 0 
AND sys.columns.[object_id] = @TABLE_ID 

SET @TRIGGERSTATEMENT = '' 

SELECT @TRIGGERSTATEMENT = @TRIGGERSTATEMENT + @vbCrLf 
+ sys.sql_modules.[definition] + @vbCrLf + 'GO' 
FROM sys.sql_modules 
WHERE [object_id] IN(SELECT [object_id] 
FROM sys.objects 
WHERE type = 'TR' 
    AND [parent_object_id] = @TABLE_ID) 

IF @TRIGGERSTATEMENT <> '' 
SET @TRIGGERSTATEMENT = @vbCrLf + 'GO' + @vbCrLf + @TRIGGERSTATEMENT 

SET @EXTENDEDPROPERTIES = '' 

SELECT @EXTENDEDPROPERTIES = @EXTENDEDPROPERTIES + @vbCrLf 
    + 'EXEC sys.sp_addextendedproperty   @name = N''' + [name] 
    + ''', @value = N''' 
    + Replace(CONVERT(VARCHAR(max), [value]), '''', 
    '''''') 
    + 
''',   @level0type = N''SCHEMA'', @level0name = [' 
    + @SCHEMANAME 
    + 
'],   @level1type = N''TABLE'', @level1name = [' 
    + @TBLNAME + '];' 
FROM Fn_listextendedproperty (NULL, 'schema', @SCHEMANAME, 'table', 
@TBLNAME, NULL, 
NULL); 

IF @EXTENDEDPROPERTIES <> '' 
SET @EXTENDEDPROPERTIES = @vbCrLf + 'GO' + @vbCrLf + @EXTENDEDPROPERTIES 

SELECT @FINALSQL = @FINALSQL + @CONSTRAINTSQLS + @CHECKCONSTSQLS 
+ @FKSQLS 

SET @FINALSQL = Substring(@FINALSQL, 1, Len(@FINALSQL) - 1); 
SET @FINALSQL = @FINALSQL + ')' + @vbCrLf; 

SELECT @FINALSQL + @INDEXSQLS + @RULESCONSTSQLS 
+ @TRIGGERSTATEMENT + @EXTENDEDPROPERTIES 
END 

go 
+0

Możesz wykonać ten wiersz powrotu na przebieg (zamiast wiersza na tabelę)? próbowałem i nie udało mi się ... dzięki –

0

W rzeczywistości nadal nie ma sposobu, aby firma Microsoft wspierała dzisiaj.

Ale można zrobić Hack:

z następującymi skryptu PowerShell można wywołać eksport DDL poprzez PowerShell:

$server = "MSSQLServer\Instance" 
$srcDB = "TestDB" 
$dump = "C:\Temp\EE\TestDB.sql" 

# Stop on any error 
$ErrorActionPreference = "stop" 

[void] [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') 
[void] [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SQlServer.SMOExtended') 
$xfer = [Microsoft.SqlServer.Management.SMO.Transfer] ([Microsoft.SqlServer.Management.SMO.Server] $server).Databases[$srcDB] 

# Set export options. 
$opts = New-Object Microsoft.SqlServer.Management.SMO.ScriptingOptions 
$opts.Filename    = $dump 
$opts.ToFileOnly   = $true 
$opts.AllowSystemObjects = $false 
$opts.Statistics   = $false 
$opts.ScriptDataCompression = $false 

$xfer.options = $opts 
$xfer.ScriptTransfer() 

Teraz wystarczy zapisać ten skrypt i wszystko to za pośrednictwem TSQL - spójrz tutaj: call PowerShell via T-SQL

... a następnie odczytać pliku tymczasowego z OPENROWSET(BULK ..., SINGLE_CLOB)

+0

Bieganie ** linux **, nie można używać Power Shell –

+0

@LeibaleEidelman z PowerShell 6 możesz, spójrz na [GitHub] (https://github.com/PowerShell/PowerShell) – ice1e0

+0

Czy istnieje sposób określenia jednej tabeli dla tego skryptu? to jest, zrzucić tabelę, indeksy, wyzwalacze i cokolwiek innego związanego z określoną tabelą ?. –

1

Można użyć MSSQL Scripter bezpośredni z Microsoft, jest całkiem nowa i wymaga niedawnej Pythona czas pracy ... ale działa na Linux, Macos i Windows