我已经创建了一个实现Microsoft.Data.Schema.ScriptDom和Microsoft.Data.Schema.ScriptDom.Sql接口的基本C#类。这两个程序集是Visual Studio数据库版(VSDB)的一部分,也是分析/脚本API的一部分。您可以分析SQL文本并输出格式化SQL脚本。有关VSDB程序集的更多信息,请参见this blog post。因为它们是可再分发的,所以我包含了程序集和PowerShell脚本here
#requires -version 2
add-type -path .\Microsoft.Data.Schema.ScriptDom.dll
add-type -path .\Microsoft.Data.Schema.ScriptDom.Sql.dll
$Source = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.Sql;
using System.IO;
public class SQLParser
{
private IScriptFragment fragment;
public SQLParser(SqlVersion sqlVersion, bool quotedIdentifier, string inputScript)
{
switch (sqlVersion)
{
case SqlVersion.Sql80:
SQLParser80 (quotedIdentifier, inputScript);
break;
case SqlVersion.Sql90:
SQLParser90 (quotedIdentifier, inputScript);
break;
case SqlVersion.Sql100:
SQLParser100 (quotedIdentifier, inputScript);
break;
}
}
private void SQLParser100 (bool quotedIdentifier, string inputScript)
{
TSql100Parser parser = new TSql100Parser(quotedIdentifier);
Parse(parser, inputScript);
}
private void SQLParser90 (bool quotedIdentifier, string inputScript)
{
TSql90Parser parser90 = new TSql90Parser(quotedIdentifier);
Parse(parser90, inputScript);
}
private void SQLParser80 (bool quotedIdentifier, string inputScript)
{
TSql80Parser parser80 = new TSql80Parser(quotedIdentifier);
Parse(parser80, inputScript);
}
private void Parse(TSql100Parser parser, string inputScript)
{
IList<ParseError> errors;
using (StringReader sr = new StringReader(inputScript))
{
fragment = parser.Parse(sr, out errors);
}
if (errors != null && errors.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (var error in errors)
{
sb.AppendLine(error.Message);
sb.AppendLine("offset " + error.Offset.ToString());
}
throw new ArgumentException("InvalidSQLScript", sb.ToString());
}
}
private void Parse(TSql90Parser parser, string inputScript)
{
IList<ParseError> errors;
using (StringReader sr = new StringReader(inputScript))
{
fragment = parser.Parse(sr, out errors);
}
if (errors != null && errors.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (var error in errors)
{
sb.AppendLine(error.Message);
sb.AppendLine("offset " + error.Offset.ToString());
}
throw new ArgumentException("InvalidSQLScript", sb.ToString());
}
}
private void Parse(TSql80Parser parser, string inputScript)
{
IList<ParseError> errors;
using (StringReader sr = new StringReader(inputScript))
{
fragment = parser.Parse(sr, out errors);
}
if (errors != null && errors.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (var error in errors)
{
sb.AppendLine(error.Message);
sb.AppendLine("offset " + error.Offset.ToString());
}
throw new ArgumentException("InvalidSQLScript", sb.ToString());
}
}
public IScriptFragment Fragment
{
get { return fragment; }
}
}
"@
$refs = @("Microsoft.Data.Schema.ScriptDom","Microsoft.Data.Schema.ScriptDom.Sql")
add-type -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru我正在使用PowerShell V2 add-type来创建运行时类型。我已经在3台不同的机器上测试了这个脚本。在一台机器上,脚本按照预期工作,在另外两台机器上,会产生以下错误。这两个引用的程序集都与PowerShell脚本放置在同一文件夹中。知道我哪里做错了吗?
PS C:\Users\u00\bin> .\SQLParser.ps1
Add-Type : (0) : Metadata file 'Microsoft.Data.Schema.ScriptDom.dll' could not be found
(1) : using System;
At C:\Users\u00\bin\SQLParser.ps1:125 char:9
+ add-type <<<< -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
+ CategoryInfo : InvalidData: (error CS0006: M...ld not be found:CompilerError) [Add-Type], Exception
+ FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
Add-Type : (0) : Metadata file 'Microsoft.Data.Schema.ScriptDom.Sql.dll' could not be found
(1) : using System;
At C:\Users\u00\bin\SQLParser.ps1:125 char:9
+ add-type <<<< -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
+ CategoryInfo : InvalidData: (error CS0006: M...ld not be found:CompilerError) [Add-Type], Exception
+ FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
Add-Type : Cannot add type. There were compilation errors.
At C:\Users\u00\bin\SQLParser.ps1:125 char:9
+ add-type <<<< -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru
+ CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationException
+ FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand发布于 2009-10-29 13:11:23
非常简单,一旦你知道了;-)
Max的示例之所以有效,是因为这些程序集位于GAC中,因此可以通过名称引用它们。您的程序集不是这样的,因此它们需要通过path引用。
您也不需要顶部的Add-Type引用,至少对于该脚本不需要--只需将最后几行更改为:
$PSScriptRoot = (Split-Path $MyInvocation.MyCommand.Path -Parent)
$refs = @("$PSScriptRoot\Microsoft.Data.Schema.ScriptDom.dll","$PSScriptRoot\Microsoft.Data.Schema.ScriptDom.Sql.dll")
add-type -ReferencedAssemblies $refs -TypeDefinition $Source -Language CSharpVersion3 -passThru发布于 2009-10-29 09:00:44
如果您将VSTSDB程序集放在与脚本相同的目录中,则不希望使用“。在相对路径中。".“将相对于调用脚本的目录。试试下面这样的代码:
$ScriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent
Add-Type -Path "$ScriptDir\Microsoft.Data.Schema.ScriptDom.dll"发布于 2009-10-29 09:33:59
我有一个样本,我在PS曲目中使用过。这是一种基本的方法,但很有效。以下是使用SMO的代码:
$Assem = ("Microsoft.SqlServer.Smo","Microsoft.SqlServer.ConnectionInfo")
$Source = @"
public class MyMSSql
{
public static string getEdition(string sqlName)
{
string sqlEdition;
Microsoft.SqlServer.Management.Smo.Server sname = new Microsoft.SqlServer.Management.Smo.Server(sqlName);
sqlEdition = sname.Information.Edition;
return sqlEdition;
}
public string getSqlEdition(string sqlName)
{
string sqlEdition;
Microsoft.SqlServer.Management.Smo.Server sname = new Microsoft.SqlServer.Management.Smo.Server(sqlName);
sqlEdition = sname.Information.Edition;
return sqlEdition;
}
}
"@;
Add-Type -ReferencedAssemblies $Assem -TypeDefinition $Source
[MyMSSql]::getEdition("MAX-PCWIN1")
#Developer Edition (64-bit)
$MySQLobj = New-Object MyMSSql
$MySQLobj.getSqlEdition("MAX-PCWIN1")希望这篇文章能给你一个提示。
最大值
https://stackoverflow.com/questions/1640905
复制相似问题