Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Korrektes Escapezeichen von durch Trennzeichen getrennten Bezeichnern in SQL Server ohne Verwendung von QUOTENAME

Ihr QuoteName Funktion muss die Länge überprüfen, da die T-SQL QUOTENAME-Funktion die maximale Länge angibt, die sie zurückgibt. Anhand Ihres Beispiels:

String.Format(@"declare @delimitedIdentifier nvarchar(258);
set @delimitedIdentifier = {0};", QuoteName(identifier));

Wenn QuoteName(identifier) länger als 258 Zeichen ist, wird er stillschweigend abgeschnitten, wenn er @delimitedIdentifier zugewiesen wird . Wenn das passiert, öffnen Sie die Möglichkeit für @delimitedIdentifier unsachgemäß zu entkommen.

Es gibt ein MSDN-Artikel von Bala Neerumalla, einem „Security Software Developer bei Microsoft“, der das Thema näher erläutert. Der Artikel enthält auch das, was ich am nächsten an "definitiver Dokumentation zum Escapezeichen von Bezeichnern in Anführungszeichen in SQL Server" gefunden habe:

Dies ist der C#-Code, den ich derzeit verwende:

/// <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 ]");
    }
}