SQL सर्वर - एक db से दूसरे में संग्रहीत कार्यविधियों की प्रतिलिपि बनाएँ


86

मैं SQL के लिए नया हूँ, और मुझे जो करने की ज़रूरत थी वह था 2 .mdf डेटाबेस को एक में मिलाना। मैंने SQL सर्वर 2008 प्रबंधक - कार्य> आयात / निर्यात तालिकाओं का उपयोग करते हुए किया था। तालिकाओं और विचारों को सफलतापूर्वक कॉपी किया गया था, लेकिन नए डेटाबेस में कोई संग्रहीत कार्यविधियाँ नहीं हैं। क्या उसे करने का कोई तरीका है?


1
यदि आप उन्हें प्रोग्रामेटिक रूप से कॉपी करना चाहते हैं, तो यहां से शुरू करें: stackoverflow.com/a/6124487/138938
जॉन क्रॉवेल

जवाबों:


137
  • डेटाबेस पर राइट क्लिक करें
  • कार्य
  • लिपियों का सृजन करें
  • स्क्रिप्ट के लिए इच्छित वस्तुओं का चयन करें
  • फाइल करने के लिए स्क्रिप्ट
  • लक्ष्य डेटाबेस के विरुद्ध उत्पन्न स्क्रिप्ट चलाएँ

नमस्ते, तेजी से उत्तर के लिए धन्यवाद। क्या आप कृपया बता सकते हैं कि लक्ष्य डेटाबेस के विरुद्ध स्क्रिप्ट का उपयोग कैसे करें। मैं इस के लिए नया हूँ।
ओक

1
@BarryKaye यदि उसके पास 30-40 संग्रहीत कार्यविधियाँ हैं, तो क्या होगा? राइट क्लिक करना थोड़ा धीमा नहीं होगा?
rvphx

@ ओक SQL प्रबंधन स्टूडियो में उत्पन्न स्क्रिप्ट फ़ाइल खोलें। कनेक्शन को अपने नए डेटाबेस में बदलें। फ़ाइल के सबसे ऊपर स्थित लाइन को बदलें जहाँ यह कहती है कि 'डेटाबेस का उपयोग करें' अपने डेटाबेस में जाएँ और निष्पादित करें।
जयमल चैहान

वाह। अब मुझे लगा कि मैं ही एकमात्र व्यक्ति हूं जिसे GUI आधारित दृष्टिकोण पसंद है !!
rvphx

10
@RajivVarma - आप डेटाबेस के लिए एक बार इस कार्य को करते हैं - प्रत्येक एसपी को नहीं! यदि आप "संग्रहीत कार्यविधियाँ" के पास शीर्ष-स्तरीय चेकबॉक्स पर टिक करते हैं, तो यह उन सभी को एक साथ चुनता है - 1 क्लिक।
बैरी केय

19

यह कोड मास्टर डेटाबेस में सभी संग्रहीत प्रक्रियाओं को लक्ष्य डेटाबेस में कॉपी करता है, आप प्रक्रिया नाम पर क्वेरी को फ़िल्टर करके अपनी पसंद की प्रक्रियाओं को कॉपी कर सकते हैं।

@sql को nvarchar (अधिकतम) के रूप में परिभाषित किया गया है, @Name लक्ष्य डेटाबेस है

DECLARE c CURSOR FOR 
   SELECT Definition
   FROM [ResiDazeMaster].[sys].[procedures] p
   INNER JOIN [ResiDazeMaster].sys.sql_modules m ON p.object_id = m.object_id

OPEN c

FETCH NEXT FROM c INTO @sql

WHILE @@FETCH_STATUS = 0 
BEGIN
   SET @sql = REPLACE(@sql,'''','''''')
   SET @sql = 'USE [' + @Name + ']; EXEC(''' + @sql + ''')'

   EXEC(@sql)

   FETCH NEXT FROM c INTO @sql
END             

CLOSE c
DEALLOCATE c

धन्यवाद! ... टिप्पणियों में, लेकिन कोड में घोषित नहीं कर रहे हैं @sqlऔर @Name:DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
datalifenyc

क्या अलग-अलग सर्वरों में ऐसा करने का कोई तरीका है? सर्वर A से सर्वर B तक?
राजाराम

5

देर से एक लेकिन अधिक जानकारी देता है जो उपयोगी हो सकता है ...

यहां उन चीजों की एक सूची दी गई है, जिन्हें आप फायदे और नुकसान के साथ कर सकते हैं

SSMS का उपयोग करके स्क्रिप्ट उत्पन्न करें

  • पेशेवरों: डिफ़ॉल्ट रूप से उपयोग करना और समर्थित करना बेहद आसान है
  • विपक्ष: स्क्रिप्ट सही निष्पादन क्रम में नहीं हो सकती हैं और यदि संग्रहीत प्रक्रिया पहले से ही द्वितीयक डेटाबेस पर मौजूद है, तो आपको त्रुटियाँ मिल सकती हैं। सुनिश्चित करें कि आप निष्पादित करने से पहले स्क्रिप्ट की समीक्षा करें।

तीसरे पक्ष के उपकरण

  • पेशेवरों: ApexSQL डिफ ( जैसे मैं उपयोग करता हूं, लेकिन रेड गेट या देव आर्ट से उपकरण जैसे कई अन्य हैं) के उपकरण एक क्लिक में दो डेटाबेसों की तुलना करेंगे और ऐसी स्क्रिप्ट उत्पन्न करेंगे जिसे आप तुरंत निष्पादित कर सकते हैं
  • विपक्ष: ये मुफ़्त नहीं हैं (अधिकांश विक्रेताओं का पूरी तरह कार्यात्मक परीक्षण हालांकि)

सिस्टम दृश्य

  • पेशेवरों: आप आसानी से देख सकते हैं कि कौन सी संग्रहीत प्रक्रियाएं द्वितीयक सर्वर पर मौजूद हैं और केवल वे ही उत्पन्न करें जो आपके पास नहीं हैं।
  • विपक्ष: थोड़ा अधिक SQL ज्ञान की आवश्यकता है

यहाँ कुछ डेटाबेस में सभी प्रक्रियाओं की एक सूची प्राप्त करना है जो किसी अन्य डेटाबेस में मौजूद नहीं है

select *
from DB1.sys.procedures P
where P.name not in 
 (select name from DB2.sys.procedures P2)

5

मैंने मूल रूप से इस पोस्ट को अपने दूरस्थ उत्पादन डेटाबेस से अपने स्थानीय विकास डेटाबेस में संग्रहीत प्रक्रियाओं की प्रतिलिपि बनाने के लिए एक समाधान की तलाश में पाया। इस सूत्र में सुझाए गए दृष्टिकोण का उपयोग करने के बाद, मुझे एहसास हुआ कि मैं तेजी से आलसी (या संसाधनपूर्ण, जो भी आप पसंद करते हैं) बढ़ता गया और चाहता था कि यह स्वचालित हो। मैं इस लिंक पर आया , जो बहुत मददगार साबित हुआ (धन्यवाद vincpa), और मैंने इसे आगे बढ़ाया, जिसके परिणामस्वरूप निम्न फ़ाइल (schema_backup.ps1):

$server             = "servername"
$database           = "databaseName"
$output_path        = "D:\prod_schema_backup"
$login = "username"
$password = "password"

$schema             = "dbo"
$table_path         = "$output_path\table\"
$storedProcs_path   = "$output_path\stp\"
$views_path         = "$output_path\view\"
$udfs_path          = "$output_path\udf\"
$textCatalog_path   = "$output_path\fulltextcat\"
$udtts_path         = "$output_path\udtt\"

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")  | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")  | out-null
$srvConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$srvConn.ServerInstance = $server
$srvConn.LoginSecure = $false
$srvConn.Login = $login
$srvConn.Password = $password
$srv        = New-Object Microsoft.SqlServer.Management.SMO.Server($srvConn)
$db         = New-Object ("Microsoft.SqlServer.Management.SMO.Database")
$tbl        = New-Object ("Microsoft.SqlServer.Management.SMO.Table")
$scripter   = New-Object Microsoft.SqlServer.Management.SMO.Scripter($srvConn)

# Get the database and table objects
$db = $srv.Databases[$database]

$tbl            = $db.tables | Where-object { $_.schema -eq $schema  -and -not $_.IsSystemObject } 
$storedProcs    = $db.StoredProcedures | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$views          = $db.Views | Where-object { $_.schema -eq $schema } 
$udfs           = $db.UserDefinedFunctions | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$catlog         = $db.FullTextCatalogs
$udtts          = $db.UserDefinedTableTypes | Where-object { $_.schema -eq $schema } 

# Set scripter options to ensure only data is scripted
$scripter.Options.ScriptSchema  = $true;
$scripter.Options.ScriptData    = $false;

#Exclude GOs after every line
$scripter.Options.NoCommandTerminator   = $false;
$scripter.Options.ToFileOnly            = $true
$scripter.Options.AllowSystemObjects    = $false
$scripter.Options.Permissions           = $true
$scripter.Options.DriAllConstraints     = $true
$scripter.Options.SchemaQualify         = $true
$scripter.Options.AnsiFile              = $true

$scripter.Options.SchemaQualifyForeignKeysReferences = $true

$scripter.Options.Indexes               = $true
$scripter.Options.DriIndexes            = $true
$scripter.Options.DriClustered          = $true
$scripter.Options.DriNonClustered       = $true
$scripter.Options.NonClusteredIndexes   = $true
$scripter.Options.ClusteredIndexes      = $true
$scripter.Options.FullTextIndexes       = $true

$scripter.Options.EnforceScriptingOptions   = $true

function CopyObjectsToFiles($objects, $outDir) {
    #clear out before 
    Remove-Item $outDir* -Force -Recurse
    if (-not (Test-Path $outDir)) {
        [System.IO.Directory]::CreateDirectory($outDir)
    }   

    foreach ($o in $objects) { 

        if ($o -ne $null) {

            $schemaPrefix = ""

            if ($o.Schema -ne $null -and $o.Schema -ne "") {
                $schemaPrefix = $o.Schema + "."
            }

            #removed the next line so I can use the filename to drop the stored proc 
            #on the destination and recreate it
            #$scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name + ".sql"
            $scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name
            Write-Host "Writing " $scripter.Options.FileName
            $scripter.EnumScript($o)
        }
    }
}

# Output the scripts
CopyObjectsToFiles $tbl $table_path
CopyObjectsToFiles $storedProcs $storedProcs_path
CopyObjectsToFiles $views $views_path
CopyObjectsToFiles $catlog $textCatalog_path
CopyObjectsToFiles $udtts $udtts_path
CopyObjectsToFiles $udfs $udfs_path

Write-Host "Finished at" (Get-Date)
$srv.ConnectionContext.Disconnect()

मेरे पास एक .bat फ़ाइल है जो इसे कॉल करती है, और टास्क शेड्यूलर से कॉल किया जाता है। पॉवरशेल फ़ाइल पर कॉल करने के बाद, मेरे पास है:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /Q "DROP PROCEDURE %f"

यह रेखा निर्देशिका को थ्रू करेगी और उन प्रक्रियाओं को छोड़ देगी जो इसे फिर से बनाने जा रही हैं। यदि यह विकास का माहौल नहीं था, तो मैं प्रोग्रामेटिक रूप से इस तरह की प्रक्रियाओं को छोड़ना नहीं चाहूंगा। मैं तो .sql करने के लिए सभी संग्रहीत कार्यविधि फ़ाइलों का नाम बदलें:

powershell Dir d:\prod_schema_backup\stp\ | Rename-Item -NewName { $_.name + ".sql" }

और फिर चलाएं:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /E /i "%f".sql

और यह सभी .sql फ़ाइलों के माध्यम से पुन: प्रसारित होता है और संग्रहीत प्रक्रियाओं को फिर से बनाता है। मुझे उम्मीद है कि इसका कोई भी हिस्सा किसी के लिए मददगार साबित होगा।


मुझे यह पसंद आ रहा है। मुझे एक साल में एक बार एक प्रोडक्शंस डीबी से बाहर संग्रह करने के लिए एक प्रक्रिया लिखना है। मैं एसक्यूएल फाइलों को लटकाए रखना नहीं चाहता, जिसके बारे में शायद अपडेट नहीं होगा क्योंकि स्कीमा विकसित होती है इसलिए मैं इसे एक खाली डीबी बनाने के लिए इसे एडैप्ट कर रहा हूं, जो डिस्क पर फाइलों को लिखने के मध्यवर्ती चरण के बिना एक लक्ष्य पर आधारित है (अधिक साफ करना)। मुझे लगता है यह इस सवाल पर सबसे अच्छा और सबसे पुन: प्रयोज्य जवाब है, यश सर!
स्टीव पेटीफ़र

3

आप SSMS की "जनरेट स्क्रिप्ट्स ..." का उपयोग करके स्क्रिप्ट कर सकते हैं जो भी आपको ट्रांसफर करने की आवश्यकता है। SSMS में स्रोत डेटाबेस पर राइट-क्लिक करें, "स्क्रिप्ट जनरेट करें ..." चुनें, और विज़ार्ड का अनुसरण करें। फिर अपनी परिणामी स्क्रिप्ट चलाएं जिसमें अब संग्रहीत कार्यविधि होगी जिसमें कथन बनाए जाएंगे।


3

उपयोग

select * from sys.procedures

अपनी सभी प्रक्रियाओं को दिखाने के लिए;

sp_helptext @objname = 'Procedure_name'

कोड प्राप्त करने के लिए

और अपनी रचनात्मकता उन सभी के माध्यम से कुछ बनाने के लिए और निर्यात कोड उत्पन्न करने के लिए :)


3

आप अन्य उत्तरों में दर्शाए गए अनुसार संग्रहित प्राप की स्क्रिप्टोफ़ उत्पन्न कर सकते हैं। एक बार स्क्रिप्ट उत्पन्न हो जाने के बाद, आप sqlcmdउन्हें लक्ष्य DB की तरह निष्पादित करने के लिए उपयोग कर सकते हैं

sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file> 

0

Mgmt Studio में, अपने मूल डेटाबेस पर राइट-क्लिक करें, फिर कार्य करें तब लिपियों को जनरेट करें ... - विज़ार्ड का अनुसरण करें।


0

सेलेक्ट डेफिनिशन + चार (13) + 'जाओ' MyDatabase.sys.sql_modules के INNER में शामिल करें MyDatabase.sys.procedures p ON [s]। [Object_id] = [p]। '' क्वेरीआउट '' c: \ SP_scripts.sql -S MyInstance -T -t -w

सपा प्राप्त करें और इसे निष्पादित करें


यह एक बहुत अच्छा समाधान है, लेकिन 1) आपको यह इंगित करना चाहिए कि पाठ या फ़ाइल आउटपुट की आवश्यकता है (ग्रिड में परिणाम प्रदर्शित नहीं करते हैं, या आप ईओएल चार्ट खो देंगे) और 2) 8k की सीमा लगती है SQL सर्वर प्रबंधन स्टूडियो में पाठ आउटपुट के लिए।
DAB

0

एक अन्य विकल्प SQL सर्वर एकीकरण सेवाओं (SSIS) का उपयोग करके संग्रहीत प्रक्रियाओं को स्थानांतरित करना है । एक कार्य है जिसे ट्रांसफर SQL सर्वर ऑब्जेक्ट्स टास्क कहा जाता है । आप निम्न वस्तुओं को स्थानांतरित करने के लिए कार्य का उपयोग कर सकते हैं:

  • टेबल्स
  • दृश्य
  • संग्रहित प्रक्रियाएं
  • उपयोगकर्ता-परिभाषित कार्य
  • चूक
  • उपयोगकर्ता-परिभाषित डेटा प्रकार
  • विभाजन के कार्य
  • विभाजन की योजनाएँ
  • स्कीमा
  • सभाओं
  • उपयोगकर्ता-परिभाषित समुच्चय
  • उपयोगकर्ता-परिभाषित प्रकार
  • XML स्कीमा संग्रह

यह ट्रांसफर SQL सर्वर ऑब्जेक्ट्स टास्क के लिए एक ग्राफिकल ट्यूटोरियल है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.