回答
如果要創建一個工具,允許用戶輸入手動一些SQL代碼,你要驗證的代碼中使用C#代碼輸入之前執行的SQL服務器上,您可以創建一個方法像這樣:
using Microsoft.Data.Schema.ScriptDom;
using Microsoft.Data.Schema.ScriptDom.Sql;
public class SqlParser
{
public List<string> Parse(string sql)
{
TSql100Parser parser = new TSql100Parser(false);
IScriptFragment fragment;
IList<ParseError> errors;
fragment = parser.Parse(new StringReader(sql), out errors);
if (errors != null && errors.Count > 0)
{
List<string> errorList = new List<string>();
foreach (var error in errors)
{
errorList.Add(error.Message);
}
return errorList;
}
return null;
}
}
由於2018年和新的數據庫版本,這可能是較新的版本:
using Microsoft.SqlServer.TransactSql.ScriptDom;
(使用npm下載:PM> Install-Package Microsoft.SqlServer.TransactSql.ScriptDom -Version 14.0.3811。1)
public bool IsSQLQueryValid(string sql, out List<string> errors)
{
errors = new List<string>();
TSql140Parser parser = new TSql140Parser(false);
TSqlFragment fragment;
IList<ParseError> parseErrors;
using (TextReader reader = new StringReader(sql))
{
fragment = parser.Parse(reader, out parseErrors);
if (parseErrors != null && parseErrors.Count > 0)
{
errors = parseErrors.Select(e => e.Message).ToList();
return false;
}
}
return true;
}
+1有趣...不知道TSql100Parser類 – 2010-07-25 16:41:08
除了從終結者電影中看到某種東西之外,還有+1,因爲我還沒有聽說過這個。這是直接鏈接到MSDN的未來問題查看器 - https://msdn.microsoft.com/en-us/library/microsoft.data.schema.scriptdom.sql.tsqlparser%28v=vs.100%29.aspx – Tommy 2016-02-10 22:59:51
有一個nuget包,他找不到(或不可能引用本地)ScriptDom dll的:https://www.nuget.org/packages/Microsoft.SqlServer.TransactSql.ScriptDom/ – 2016-05-11 14:41:39
「有效」SQL意味着什麼?語法或結果?
驗證語法的唯一方法是在SQL Server中執行SQL。您是否考慮過在事務中運行SQL,然後在最後進行回滾?
Begin Transaction
--execute your code between the 'Begin Transaction' and the 'rollback' keywords.
...
--example
Insert into mytable(ID)Values(2)
...
Rollback
我該怎麼做?你能寫例子嗎?謝謝。 – 2010-07-18 15:15:38
@Tamifist:使用TransactionScope並從不調用Transaction.Complete。這裏有很多關於TransactionScope的例子,但是要記住,你必須首先創建你的TransactionScope,並且裏面的SqlConnection。 – 2010-07-18 15:43:35
SSMS有這樣的一種方式。
如果您使用SQL事件探查器,您會看到它執行SET PARSEONLY ON
,然後SQL和SET PARSEONLY OFF
以及任何錯誤都會上升而不編譯或執行查詢。
SET PARSEONLY ON;
SELECT * FROM Table; --Query To Parse
SET PARSEONLY OFF;
我從來沒有試過這種從C#,但我看不出有什麼理由不應該工作,它從SSMS工作畢竟。
正如馬丁·史密斯指出,在評論中,你可以使用SET NOEXEC ON
MSDN說以下有關這兩個命令。
當SET NOEXEC爲ON時,SQL Server 編譯的Transact-SQL語句 每批但不執行它們。 當SET NOEXEC爲OFF時,所有批次 在編譯後執行。
當SET PARSEONLY爲ON時,SQL Server僅解析語句。當 SET PARSEONLY爲OFF時,SQL Server 編譯並執行該語句。
這表示NOEXEC
也將編譯查詢,其中PARSEONLY
不會。因此NOEXEC
可能會發現PARSEONLY
沒有的錯誤。用法是一樣的。
SET NOEXEC ON;
SELECT * FROM Table; --Query To Parse
SET NOEXEC OFF;
我覺得'NO EXEC'會捕獲更多的東西。http://stackoverflow.com/questions/3084387/how-can-i-program-check-parse-the-validity-of-a-tsql-statement – 2010-07-18 16:07:32
@Martin - 感謝您的信息 – 2010-07-18 16:11:22
根據Martin Smith鏈接的帖子,您可能還想要嘗試SET FMTONLY ON。這將識別丟失的表格等等。 – cbp 2012-06-27 06:29:48
我知道這個問題是關於.NET 2.0的,但對某人來說可能很有趣。在最新版本的Microsoft SQL Server中,查詢的驗證功能稍有變化。 命名空間是Microsoft.SqlServer.TransactSql.ScriptDom
而不是Microsoft.Data.Schema.ScriptDom
。
哪裏可以找到這個圖書館?
的路徑庫%programfiles(x86)%\Microsoft SQL Server\120\SDK\Assemblies
如果你不能找到這個庫,並安裝Microsoft SQL Server,嘗試從120
改變110
或100
並使用相應的解析器(分別爲TSql110Parser
或TSql100Parser
)。
如何使用?
我有兩個擴展:第一個擴展檢查輸入字符串是否是有效的SQL查詢,第二個擴展可用於從解析中獲取錯誤。
using Microsoft.SqlServer.TransactSql.ScriptDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public static class SqlStringExtensions
{
public static bool IsValidSql(this string str)
{
return !str.ValidateSql().Any();
}
public static IEnumerable<string> ValidateSql(this string str)
{
if (string.IsNullOrWhiteSpace(str))
{
return new[] { "SQL query should be non empty." };
}
var parser = new TSql120Parser(false);
IList<ParseError> errors;
using (var reader = new StringReader(str))
{
parser.Parse(reader, out errors);
}
return errors.Select(err => err.Message);
}
}
Additionaly,我檢查輸入的SQL查詢不爲空或空,因爲解析器認爲空字符串是完全有效的(我不判斷它)。
如何測試?
有三個NUnit測試顯示瞭如何使用此擴展。
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
[TestFixture]
public class SqlStringExtensionsTests
{
[Test]
public void ValidateSql_InvalidSql_ReturnsErrorMessages()
{
// this example doesn't contain "," between the field names
string invalidSql = "SELECT /*comment*/ " +
"CustomerID AS ID CustomerNumber FROM Customers";
IEnumerable<string> results = invalidSql.ValidateSql();
Assert.AreNotEqual(0, results.Count());
}
[Test]
public void IsValidSql_ValidSql_ReturnsTrue()
{
string validSql = "SELECT /*comment*/ " +
"CustomerID AS ID, CustomerNumber FROM Customers";
bool result = validSql.IsValidSql();
Assert.AreEqual(true, result);
}
[Test]
public void IsValidSql_InvalidSql_ReturnsFalse()
{
// this example doesn't contain "," between the field names
string invalidSql = "SELECT /*comment*/ "+
" CustomerID AS ID CustomerNumber FROM Customers";
bool result = invalidSql.IsValidSql();
Assert.AreEqual(false, result);
}
}
該文件夾中有三個DLL 。 – 2016-02-23 07:18:42
@AndersLindén請你詳細描述一下這個問題嗎? – 2016-02-23 11:07:57
嗯,我只是選擇了一個DLL,它工作。然而,選擇正確的火箭科學任務並非是一項任務。 – 2016-02-23 14:30:18
- 1. PL/SQL腳本驗證
- 2. 驗證您的SQL Server DML腳本
- 3. 引腳代碼驗證命令?
- 4. HTTP基本驗證的純JavaScript代碼?
- 5. Shell腳本來驗證根密碼
- 6. python腳本獲取驗證碼
- 7. 驗證dbms_sql.execute執行代碼PL/SQL
- 8. 未執行PL/SQL代碼驗證
- 9. Java腳本驗證
- 10. Java腳本驗證
- 11. 驗證HTML5 DOCTYPE。驗證本地主機上的源代碼
- 12. shell腳本驗證eclipse代碼格式化器xml
- 13. Emacs代碼驗證
- 14. 驗證JavaScript代碼
- 15. 驗證python腳本的
- 16. 下拉驗證的腳本
- 17. Url驗證我的腳本
- 18. 通過vb.net使用SQL腳本代碼
- 19. 我可以讓SQL 2008 Management Studio驗證SQL 2005的代碼嗎?
- 20. PHP身份驗證腳本
- 21. Xcode plist驗證腳本
- 22. Java腳本表單驗證
- 23. Freeradius和PHP驗證腳本
- 24. 驗證在Java腳本
- 25. 腳本驗證錯誤
- 26. jQuery驗證腳本更正
- 27. 調試PHP驗證腳本
- 28. HTML驗證/腳本JS
- 29. 數據驗證腳本
- 30. mod_wsgi身份驗證腳本
相關(但沒有C#角)http://stackoverflow.com/questions/3084387/how-can-i-programmatically-check-parse-the-validity-of-a-tsql-statement – 2010-07-18 16:03:34
可能重複的[SQL遷移工具](http://stackoverflow.com/questions/3272894/sql-migration-tool) – 2010-07-18 16:06:04
@ p.campbell然後將其標記爲重複。 – 2016-02-10 22:56:35