如何使用 Scripter 仅创建特定的删除语句
How to create only specific delete statements using Scripter
我用的Scripter class to give me a script for the data out of an existing database. I want to script a dataset that can be inserted into a production database. We are doing this to test if an installation of our Software是正确的
遗憾的是,稍后必须删除数据集,不能留下任何条目,以免干扰我们客户的数据。所以我需要的是 INSERT 和 DELTE 语句。目前都是人工维护,负担太大
很好,所以我就去执行了 Scripter 两次(一次用于 INSERT,一次用于 DELETE)
问题是,当将 ScriptDrops 设置为 true 时,输出的格式为
DELETE FROM [dbo].[TableName]
我想要的是以下形式:
DELETE FROM [dbo].[TableName] WHERE ID = 'GUID'
从技术上讲这是可能的,因为所有表上都有主键。
脚本编写器 class 还必须以某种形式知道这些事情,因为它还通过外键获得正确的 DELETE 语句(依赖项)的顺序。
如有任何帮助,我们将不胜感激。
以下是我用来导出数据的 2 个 PowerShell 脚本:
ScriptRepositoryData.ps1
$scriptPath = $MyInvocation.MyCommand.Path
$scriptDirectory = Split-Path $scriptPath -Parent
. $scriptDirectory\DatabaseScripting.ps1
$filepath='c:\data.sql'
$database='ECMS_Repository'
$tablesToExclude = @(
"SomeUnwantedTable"
)
$tablesListFromDatabase = GetTableList $database
$tablesArray = @()
$tablesListFromDatabase |% {
if (-not $tablesToExclude.Contains($_.Name.ToString()))
{
$tablesArray += $_.Name
}
}
ScriptInsert $database $tablesArray $filepath
数据库脚本。ps1
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended") | out-null
Function GetTableList ($database)
{
Invoke-SqlCmd -Database $database -query "SELECT * FROM sys.tables"
}
Function ScriptInsert ($database, $tables, $destination)
{
try {
$serverMO = new-object ("Microsoft.SqlServer.Management.Smo.Server") "localhost"
if ($serverMO.Version -eq $null) {Throw "Can't find the instance localhost"}
$urnsToScript = New-Object Microsoft.SqlServer.Management.Smo.UrnCollection
$databaseMO = $serverMO.Databases.Item("ECMS_Repository")
if ($databaseMO.Name -ne $database) {Throw "Can't find the database $database"}
$tables |% {
$tableListMO = $databaseMO.Tables.Item($_, "dbo")
$tableListMO |% {
$urnsToScript.Add($_.Urn)
}
}
$scripter = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') $serverMO
$scripter.Options.ScriptSchema = $False;
$scripter.Options.ScriptData = $true;
$scripter.Options.ScriptDrops = $true;
$scripter.Options.ScriptAlter = $true;
$scripter.Options.NoCommandTerminator = $true;
$scripter.Options.Filename = $destination;
$scripter.Options.ToFileOnly = $true
$scripter.Options.Encoding = [System.Text.Encoding]::UTF8
$scripter.EnumScript($urnsToScript)
Write-Host -ForegroundColor Green "Done"
}
catch {
Write-Host
Write-Host -ForegroundColor Red "Error occured"
Write-Host
Write-Host $_.Exception.ToString()
Write-Host
}
}
不幸的是,我没有找到使用 Sql 管理对象执行此操作的方法。
无论如何,我现在使用 Scripter 的输出和 select 每个 table 的 ID。然后我使用 ID 更改看起来像
的每一行
DELETE FROM [dbo].[tableName]
对此:
DELETE FROM [dbo].[tableName] WHERE ID IN ('guid1', 'guid2')
我是这样做的:
$content = Get-Content $destination
Clear-Content $destination
$content |% {
$line = $_
$table = $line.Replace("DELETE FROM [dbo].[","").Replace("]","")
$query = "SELECT ID, ClassID FROM" + $_
$idsAsQueryResult = Invoke-SqlCmd -Database $database -query $query
$ids = $idsAsQueryResult | Select-Object -Expand ID
if ($ids -ne $null) {
$joinedIDs = [string]::Join("','",$ids)
$newLine = $line + " WHERE ID IN ('" + $joinedIDs + "')"
Add-Content $destination $newLine
}
}
其中 $destination 是使用 Scripter class 生成的脚本,$database 是包含数据库名称的字符串。
我不得不 select 第二列(由于我们 OR mapper 重新存储,所有 table 上都有 ClassID),因为 [=31] 中出现了一些奇怪的错误=]-我不完全理解的对象。
这当然只有效,因为所有 table 都有主键,并且所有主键都命名为 ID,而不是组合主键或其他东西。
对于其他更复杂的数据库模式,您当然可以通过 SQL 管理对象提取主键信息来实现相同的目的。
我用的Scripter class to give me a script for the data out of an existing database. I want to script a dataset that can be inserted into a production database. We are doing this to test if an installation of our Software是正确的
遗憾的是,稍后必须删除数据集,不能留下任何条目,以免干扰我们客户的数据。所以我需要的是 INSERT 和 DELTE 语句。目前都是人工维护,负担太大
很好,所以我就去执行了 Scripter 两次(一次用于 INSERT,一次用于 DELETE)
问题是,当将 ScriptDrops 设置为 true 时,输出的格式为
DELETE FROM [dbo].[TableName]
我想要的是以下形式:
DELETE FROM [dbo].[TableName] WHERE ID = 'GUID'
从技术上讲这是可能的,因为所有表上都有主键。 脚本编写器 class 还必须以某种形式知道这些事情,因为它还通过外键获得正确的 DELETE 语句(依赖项)的顺序。
如有任何帮助,我们将不胜感激。
以下是我用来导出数据的 2 个 PowerShell 脚本:
ScriptRepositoryData.ps1
$scriptPath = $MyInvocation.MyCommand.Path
$scriptDirectory = Split-Path $scriptPath -Parent
. $scriptDirectory\DatabaseScripting.ps1
$filepath='c:\data.sql'
$database='ECMS_Repository'
$tablesToExclude = @(
"SomeUnwantedTable"
)
$tablesListFromDatabase = GetTableList $database
$tablesArray = @()
$tablesListFromDatabase |% {
if (-not $tablesToExclude.Contains($_.Name.ToString()))
{
$tablesArray += $_.Name
}
}
ScriptInsert $database $tablesArray $filepath
数据库脚本。ps1
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMOExtended") | out-null
Function GetTableList ($database)
{
Invoke-SqlCmd -Database $database -query "SELECT * FROM sys.tables"
}
Function ScriptInsert ($database, $tables, $destination)
{
try {
$serverMO = new-object ("Microsoft.SqlServer.Management.Smo.Server") "localhost"
if ($serverMO.Version -eq $null) {Throw "Can't find the instance localhost"}
$urnsToScript = New-Object Microsoft.SqlServer.Management.Smo.UrnCollection
$databaseMO = $serverMO.Databases.Item("ECMS_Repository")
if ($databaseMO.Name -ne $database) {Throw "Can't find the database $database"}
$tables |% {
$tableListMO = $databaseMO.Tables.Item($_, "dbo")
$tableListMO |% {
$urnsToScript.Add($_.Urn)
}
}
$scripter = new-object ('Microsoft.SqlServer.Management.Smo.Scripter') $serverMO
$scripter.Options.ScriptSchema = $False;
$scripter.Options.ScriptData = $true;
$scripter.Options.ScriptDrops = $true;
$scripter.Options.ScriptAlter = $true;
$scripter.Options.NoCommandTerminator = $true;
$scripter.Options.Filename = $destination;
$scripter.Options.ToFileOnly = $true
$scripter.Options.Encoding = [System.Text.Encoding]::UTF8
$scripter.EnumScript($urnsToScript)
Write-Host -ForegroundColor Green "Done"
}
catch {
Write-Host
Write-Host -ForegroundColor Red "Error occured"
Write-Host
Write-Host $_.Exception.ToString()
Write-Host
}
}
不幸的是,我没有找到使用 Sql 管理对象执行此操作的方法。
无论如何,我现在使用 Scripter 的输出和 select 每个 table 的 ID。然后我使用 ID 更改看起来像
的每一行DELETE FROM [dbo].[tableName]
对此:
DELETE FROM [dbo].[tableName] WHERE ID IN ('guid1', 'guid2')
我是这样做的:
$content = Get-Content $destination
Clear-Content $destination
$content |% {
$line = $_
$table = $line.Replace("DELETE FROM [dbo].[","").Replace("]","")
$query = "SELECT ID, ClassID FROM" + $_
$idsAsQueryResult = Invoke-SqlCmd -Database $database -query $query
$ids = $idsAsQueryResult | Select-Object -Expand ID
if ($ids -ne $null) {
$joinedIDs = [string]::Join("','",$ids)
$newLine = $line + " WHERE ID IN ('" + $joinedIDs + "')"
Add-Content $destination $newLine
}
}
其中 $destination 是使用 Scripter class 生成的脚本,$database 是包含数据库名称的字符串。
我不得不 select 第二列(由于我们 OR mapper 重新存储,所有 table 上都有 ClassID),因为 [=31] 中出现了一些奇怪的错误=]-我不完全理解的对象。
这当然只有效,因为所有 table 都有主键,并且所有主键都命名为 ID,而不是组合主键或其他东西。 对于其他更复杂的数据库模式,您当然可以通过 SQL 管理对象提取主键信息来实现相同的目的。