QuoteName
. Anda fungsi perlu memeriksa panjangnya, karena fungsi T-SQL QUOTENAME menentukan panjang maksimum yang dikembalikannya. Menggunakan contoh Anda:
String.Format(@"declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = {0};", QuoteName(identifier));
Jika QuoteName(identifier)
lebih panjang dari 258 karakter, akan dipotong secara diam-diam saat ditetapkan ke @delimitedIdentifier
. Ketika itu terjadi, Anda membuka kemungkinan untuk @delimitedIdentifier
untuk melarikan diri secara tidak benar.
Ada sebuah Artikel MSDN oleh Bala Neerumalla, "pengembang perangkat lunak keamanan di Microsoft", yang menjelaskan topik ini secara lebih mendalam. Artikel ini juga berisi hal terdekat yang saya temukan dengan "dokumentasi definitif tentang cara menghindari pengenal yang dikutip di SQL Server":
Ini adalah kode C# yang saya gunakan saat ini:
/// <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 ]");
}
}