Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Popraw escaping rozdzielanych identyfikatorów w SQL Server bez użycia QUOTENAME

Twój QuoteName funkcja musi sprawdzić długość, ponieważ funkcja T-SQL QUOTENAME określa maksymalną zwracaną długość. Na twoim przykładzie:

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

Jeśli QuoteName(identifier) jest dłuższy niż 258 znaków, zostanie po cichu obcięty po przypisaniu do @delimitedIdentifier . Kiedy tak się stanie, otwierasz możliwość dla @delimitedIdentifier do niewłaściwej ucieczki.

Istnieje an Artykuł MSDN autorstwa Bala Neerumalla, "programisty bezpieczeństwa w firmie Microsoft", który wyjaśnia temat bardziej szczegółowo. Artykuł zawiera również najbardziej zbliżoną rzecz, jaką znalazłem do „ostatecznej dokumentacji na temat tego, jak uciec przed cytowanymi identyfikatorami w SQL Server”:

To jest kod C#, którego obecnie używam:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Skrypt SQL do zmiany WSZYSTKICH kluczy obcych, aby dodać ON DELETE CASCADE

  2. Jak liczyć miejsca dziesiętne w SQL?

  3. „Zapytanie niedozwolone w Waitfor” Błąd 101 w SQL Server

  4. SQL:Normalizacja bazy danych przy zachowaniu ograniczeń

  5. Podziel słowa z wielką literą w sql