SQL Server - คัดลอกกระบวนงานที่จัดเก็บจากฐานข้อมูลหนึ่งไปยังอีกฐานข้อมูลหนึ่ง


87

ฉันเพิ่งเริ่มใช้ SQL และสิ่งที่ฉันต้องทำคือการรวมฐานข้อมูล 2 .mdf เข้าด้วยกัน ฉันทำอย่างนั้นโดยใช้ SQL Server 2008 Manager - Tasks> Import / Export ตารางและมุมมองถูกคัดลอกสำเร็จ แต่ไม่มีกระบวนงานที่จัดเก็บไว้ในฐานข้อมูลใหม่ มีวิธีใดบ้างที่จะทำเช่นนั้น?


1
หากคุณต้องการคัดลอกโดยใช้โปรแกรมให้เริ่มที่นี่: stackoverflow.com/a/6124487/138938
Jon Crowell

คำตอบ:


138
  • คลิกขวาที่ฐานข้อมูล
  • งาน
  • สร้างสคริปต์
  • เลือกวัตถุที่คุณต้องการเขียนสคริปต์
  • สคริปต์เป็นไฟล์
  • รันสคริปต์ที่สร้างขึ้นกับฐานข้อมูลเป้าหมาย

สวัสดีขอบคุณสำหรับการตอบกลับอย่างรวดเร็ว คุณช่วยอธิบายวิธีใช้สคริปต์กับฐานข้อมูลเป้าหมายได้ไหม ฉันยังใหม่กับสิ่งนี้
โอ๊

1
@BarryKaye เกิดอะไรขึ้นถ้าเขามีขั้นตอนการจัดเก็บ 30-40? คลิกขวาจะไม่ช้าไปหน่อยเหรอ?
rvphx

@Oak เปิดไฟล์สร้างสคริปต์ใน SQL Management Studio เปลี่ยนการเชื่อมต่อกับฐานข้อมูลใหม่ของคุณ เปลี่ยนบรรทัดที่ด้านบนสุดของไฟล์ที่ระบุว่า 'Use DatabaseName' ไปที่ฐานข้อมูลของคุณและดำเนินการ
Jaimal Chohan

ว้าว. ตอนนี้คิดว่าเป็นคนเดียวที่ชอบ GUI based approach !!
rvphx

10
@RajivVarma - คุณทำภารกิจนี้ครั้งเดียวสำหรับฐานข้อมูลไม่ใช่แต่ละ SP! หากคุณเลือกช่องทำเครื่องหมายระดับบนสุดข้าง "ขั้นตอนที่จัดเก็บ" จะเป็นการเลือกทั้งหมดพร้อมกัน - คลิก 1 ครั้ง
Barry Kaye

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?
Rajaram1991

5

ช้าไป แต่ให้รายละเอียดเพิ่มเติมที่อาจเป็นประโยชน์ ...

นี่คือรายการสิ่งที่คุณสามารถทำได้พร้อมข้อดีและข้อเสีย

สร้างสคริปต์โดยใช้ SSMS

  • ข้อดี:ใช้งานง่ายมากและรองรับโดยค่าเริ่มต้น
  • จุดด้อย:สคริปต์อาจไม่อยู่ในลำดับการดำเนินการที่ถูกต้องและคุณอาจได้รับข้อผิดพลาดหากกระบวนงานที่เก็บไว้มีอยู่แล้วในฐานข้อมูลรอง ตรวจสอบให้แน่ใจว่าคุณได้ตรวจสอบสคริปต์ก่อนดำเนินการ

เครื่องมือของบุคคลที่สาม

  • จุดเด่น:เครื่องมือเช่นApexSQL Diff (นี่คือสิ่งที่ฉันใช้ แต่มีเครื่องมืออื่น ๆ อีกมากมายเช่นเครื่องมือจาก Red Gate หรือ Dev Art) จะเปรียบเทียบฐานข้อมูลสองฐานข้อมูลในคลิกเดียวและสร้างสคริปต์ที่คุณสามารถดำเนินการได้ทันที
  • จุดด้อย:สิ่งเหล่านี้ไม่ฟรี (ผู้ขายส่วนใหญ่มีการทดลองใช้งานอย่างสมบูรณ์)

มุมมองระบบ

  • ข้อดี:คุณสามารถดูได้อย่างง่ายดายว่ามีโพรซีเดอร์ที่จัดเก็บไว้บนเซิร์ฟเวอร์รองและสร้างเฉพาะขั้นตอนที่คุณไม่มีเท่านั้น
  • จุดด้อย:ต้องการความรู้ 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 ที่เรียกสิ่งนี้และถูกเรียกจาก Task Scheduler หลังจากโทรไปที่ไฟล์ Powershell ฉันมี:

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 ทั้งหมดและสร้างโพรซีเดอร์ที่เก็บไว้ใหม่ ฉันหวังว่าส่วนใดส่วนหนึ่งของสิ่งนี้จะเป็นประโยชน์กับใครบางคน


ฉันชอบสิ่งนี้ ฉันต้องเขียนกระบวนการจัดเก็บชิ้นส่วนจากฐานข้อมูลการผลิตครั้งละหนึ่งปี ฉันไม่ต้องการที่จะต้องมีไฟล์ SQL ที่แขวนอยู่ซึ่งอาจจะไม่ได้รับการอัปเดตเมื่อสคีมาพัฒนาดังนั้นฉันจึงปรับสิ่งนี้เพื่อสร้างฐานข้อมูลว่างตามเป้าหมายโดยไม่มีขั้นตอนกลางในการเขียนไฟล์ลงดิสก์ (เพิ่มเติม ในการทำความสะอาด). ฉันคิดว่านี่อาจเป็นคำตอบที่ดีที่สุดและใช้งานได้มากที่สุดสำหรับคำถามนี้ขอแสดงความนับถือ!
Steve Pettifer

3

คุณสามารถใช้ฟังก์ชัน "สร้างสคริปต์ ... " ของ SSMS เพื่อเขียนสคริปต์สิ่งที่คุณต้องการในการถ่ายโอน คลิกขวาที่ฐานข้อมูลต้นทางใน SSMS เลือก "Generate Scripts ... " และทำตามวิซาร์ด จากนั้นรันสคริปต์ผลลัพธ์ของคุณซึ่งตอนนี้จะมีคำสั่งสร้างกระบวนงานที่เก็บไว้


3

ใช้

select * from sys.procedures

เพื่อแสดงขั้นตอนทั้งหมดของคุณ

sp_helptext @objname = 'Procedure_name'

เพื่อรับรหัส

และความคิดสร้างสรรค์ของคุณในการสร้างบางสิ่งเพื่อวนลูปทั้งหมดและสร้างรหัสส่งออก :)


3

คุณสามารถสร้าง script ของ proc ที่เก็บไว้ตามที่ปรากฎในคำตอบอื่น ๆ เมื่อสร้างสคริปต์แล้วคุณสามารถใช้sqlcmdเพื่อดำเนินการกับฐานข้อมูลเป้าหมายเช่น

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


0

SELECT definition + char (13) + 'GO' FROM MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures p ON [s]. [object_id] = [p]. [object_id] WHERE p.name LIKE 'Something% '"queryout" c: \ SP_scripts.sql -S MyInstance -T -t -w

รับ sp และดำเนินการ


นี่เป็นทางออกที่ดีมาก แต่ 1) คุณควรชี้ให้เห็นว่าจำเป็นต้องมีเอาต์พุตข้อความหรือไฟล์ (อย่าแสดงผลลัพธ์ในตารางมิฉะนั้นคุณจะสูญเสียตัวอักษร EOL) และ 2) ดูเหมือนว่าจะมีขีด จำกัด 8k สำหรับเอาต์พุตข้อความในสตูดิโอการจัดการเซิร์ฟเวอร์ SQL
DAB

0

อีกตัวเลือกหนึ่งคือการถ่ายโอนวิธีการเก็บใช้บริการในการรวมเซิร์ฟเวอร์ SQL (SSIS) มีงานที่เรียกว่าการถ่ายโอน SQL Server วัตถุงาน คุณสามารถใช้งานเพื่อถ่ายโอนรายการต่อไปนี้:

  • ตาราง
  • มุมมอง
  • กระบวนงานที่จัดเก็บ
  • ฟังก์ชันที่ผู้ใช้กำหนดเอง
  • ค่าเริ่มต้น
  • ประเภทข้อมูลที่ผู้ใช้กำหนด
  • ฟังก์ชันพาร์ติชัน
  • โครงร่างพาร์ติชัน
  • Schemas
  • แอสเซมบลี
  • User-Defined Aggregates
  • ประเภทที่ผู้ใช้กำหนด
  • XML Schema Collection

เป็นการสอนแบบกราฟิกสำหรับงาน Transfer SQL Server Objects

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.