QuoteName
của bạn hàm cần kiểm tra độ dài, vì hàm T-SQL QUOTENAME chỉ định độ dài tối đa mà nó trả về. Sử dụng ví dụ của bạn:
String.Format(@"declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = {0};", QuoteName(identifier));
If QuoteName(identifier)
dài hơn 258 ký tự, nó sẽ bị cắt ngắn khi được gán cho @delimitedIdentifier
. Khi điều đó xảy ra, bạn sẽ mở ra khả năng cho @delimitedIdentifier
được thoát không đúng cách.
Có an Bài báo MSDN của Bala Neerumalla, một "nhà phát triển phần mềm bảo mật tại Microsoft", giải thích sâu hơn về chủ đề này. Bài viết cũng chứa điều gần nhất mà tôi đã tìm thấy về "tài liệu cuối cùng về cách thoát mã nhận dạng được trích dẫn trong SQL Server":
Đây là mã C # mà tôi hiện đang sử dụng:
/// <summary>
/// Returns a string with the delimiters added to make the input string
/// a valid SQL Server delimited identifier. Brackets are used as the
/// delimiter. Unlike the T-SQL version, an ArgumentException is thrown
/// instead of returning a null for invalid arguments.
/// </summary>
/// <param name="name">sysname, limited to 128 characters.</param>
/// <returns>An escaped identifier, no longer than 258 characters.</returns>
public static string QuoteName(string name) { return QuoteName(name, '['); }
/// <summary>
/// Returns a string with the delimiters added to make the input string
/// a valid SQL Server delimited identifier. Unlike the T-SQL version,
/// an ArgumentException is thrown instead of returning a null for
/// invalid arguments.
/// </summary>
/// <param name="name">sysname, limited to 128 characters.</param>
/// <param name="quoteCharacter">Can be a single quotation mark ( ' ), a
/// left or right bracket ( [] ), or a double quotation mark ( " ).</param>
/// <returns>An escaped identifier, no longer than 258 characters.</returns>
public static string QuoteName(string name, char quoteCharacter) {
name = name ?? String.Empty;
const int sysnameLength = 128;
if (name.Length > sysnameLength) {
throw new ArgumentException(String.Format(
"name is longer than {0} characters", sysnameLength));
}
switch (quoteCharacter) {
case '\'':
return String.Format("'{0}'", name.Replace("'", "''"));
case '"':
return String.Format("\"{0}\"", name.Replace("\"", "\"\""));
case '[':
case ']':
return String.Format("[{0}]", name.Replace("]", "]]"));
default:
throw new ArgumentException(
"quoteCharacter must be one of: ', \", [, or ]");
}
}