我認爲這是非常清晰地寫出來與參數的SQL查詢,並有主SELECT查詢前幾DECLARE @p1 type;
和SET @p1 = 'value';
線和留在SqlCommand
實例不變原來的查詢文本。我有一些示例代碼,如果你想看到這一點,可以這樣做。
如果您確實堅持在查詢文本中簡單地進行參數值替換,那麼找到您正在與之通話的特定於服務器的T-SQL語法,解析查詢,直到找到參數引用,並根據T-SQL語法的字符串轉義規則將其替換爲文本。
編輯:
因爲我這樣一個富於幻想的人,我會得到你開始用自己的方式與適當的轉義輸出格式的SQL參數。這是不完整的,因爲它不處理man和SQL Server已知的每種數據庫類型,但它爲我完成了工作,因爲它處理了我最常用的類型。正如我在我的評論中所說的,只需將單引號字符作爲連續的兩個單引號字符轉義似乎足以進行正確的字符串轉義。您必須對各種SQL Server版本使用的T-SQL語法進行雙倍和三倍的檢查,以確保這是足夠好的。
private static string FormatSqlValue(System.Data.Common.DbParameter prm)
{
if (prm.Value == DBNull.Value) return "NULL";
switch (prm.DbType)
{
case System.Data.DbType.Int32: return (prm.Value.ToString());
case System.Data.DbType.String: return String.Format("'{0}'", ScrubSqlString((string)prm.Value));
case System.Data.DbType.AnsiString: return String.Format("'{0}'", ScrubSqlString((string)prm.Value));
case System.Data.DbType.Boolean: return ((bool)prm.Value ? "1" : "0");
case System.Data.DbType.DateTime: return String.Format("'{0}'", prm.Value.ToString());
case System.Data.DbType.DateTime2: return String.Format("'{0}'", prm.Value.ToString());
case System.Data.DbType.Decimal: return (prm.Value.ToString());
case System.Data.DbType.Guid: return String.Format("'{0}'", prm.Value.ToString());
case System.Data.DbType.Double: return (prm.Value.ToString());
case System.Data.DbType.Byte: return (prm.Value.ToString());
// TODO: more conversions.
default: return (prm.DbType.ToString());
}
}
private static string FormatSqlValue(Type type, object value)
{
if (value == null)
return "NULL";
// Handle Nullable<T> types:
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// If the Nullabe<T> value has been found to have !HasValue, return "NULL":
if (!(bool)type.GetProperty("HasValue").GetValue(value, null))
return "NULL";
// Try our best to format the underlying non-nullable value now:
return FormatSqlValue(type.GetGenericArguments()[0], type.GetProperty("Value").GetValue(value, null));
}
if (type == typeof(Int32)) return value.ToString();
if (type == typeof(String)) return String.Format("'{0}'", ScrubSqlString((string)value));
if (type == typeof(Boolean)) return ((bool)value ? "1" : "0");
if (type == typeof(DateTime)) return String.Format("'{0}'", value.ToString());
if (type == typeof(Decimal)) return (value.ToString());
if (type == typeof(Guid)) return String.Format("'{0}'", value.ToString());
if (type == typeof(Double)) return (value.ToString());
if (type == typeof(Byte)) return (value.ToString());
// TODO: complete the mapping...
return value.ToString();
}
private static string ScrubSqlString(string value)
{
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < value.Length)
{
if (value[i] == '\'')
{
sb.Append("\'\'");
++i;
}
else
{
sb.Append(value[i]);
++i;
}
}
return sb.ToString();
}
private static string FormatSqlParameter(System.Data.Common.DbParameter prm)
{
StringBuilder sbDecl = new StringBuilder();
sbDecl.Append(prm.ParameterName);
sbDecl.Append(' ');
switch (prm.DbType)
{
case System.Data.DbType.Int32: sbDecl.Append("int"); break;
// SQL does not like defining nvarchar(0).
case System.Data.DbType.String: sbDecl.AppendFormat("nvarchar({0})", prm.Size == -1 ? "max" : prm.Size == 0 ? "1" : prm.Size.ToString()); break;
// SQL does not like defining varchar(0).
case System.Data.DbType.AnsiString: sbDecl.AppendFormat("varchar({0})", prm.Size == -1 ? "max" : prm.Size == 0 ? "1" : prm.Size.ToString()); break;
case System.Data.DbType.Boolean: sbDecl.Append("bit"); break;
case System.Data.DbType.DateTime: sbDecl.Append("datetime"); break;
case System.Data.DbType.DateTime2: sbDecl.Append("datetime2"); break;
case System.Data.DbType.Decimal: sbDecl.Append("decimal"); break; // FIXME: no precision info in DbParameter!
case System.Data.DbType.Guid: sbDecl.Append("uniqueidentifier"); break;
case System.Data.DbType.Double: sbDecl.Append("double"); break;
case System.Data.DbType.Byte: sbDecl.Append("tinyint"); break;
// TODO: more conversions.
default: sbDecl.Append(prm.DbType.ToString()); break;
}
return sbDecl.ToString();
}
我不想被否定,但正如其他問題已經澄清 - 並且正如您自己提到的那樣 - 您要查找的TSQL字符串永遠不會生成。所以我不確定你想要得到什麼答案,除了自己推出或修改你的應用程序? – Pondlife 2010-10-15 14:55:02
@Pondlife:我希望得到這樣的答案:「是的,我之前遇到過這個問題,並且我已經編寫併發布了一個C#/ VB {鏈接到源代碼}的例程,它根據在{link to MSDN}找到SQL Server轉義規範。「 – Heinzi 2010-10-15 15:00:22