Unikanie nazw kolumn podobnych do słów kluczowych w Postgres


139

Jeśli kolumna w tabeli Postgresa ma nazwę year, jak powinno wyglądać INSERTzapytanie, aby ustawić wartość dla tej kolumny?

Np .: INSERT INTO table (id, name, year) VALUES ( ... );podaje błąd w pobliżu słowa roku .

Odpowiedzi:


218

Wystarczy ująć je yearw podwójne cudzysłowy, aby nie były interpretowane jako słowo kluczowe :

INSERT INTO table (id, name, "year") VALUES ( ... );

Z dokumentacji :

Istnieje drugi rodzaj identyfikatora: identyfikator rozdzielany lub identyfikator w cudzysłowie. Tworzy się przez ujęcie dowolnej sekwencji znaków w cudzysłów ("). Identyfikator rozdzielany jest zawsze identyfikatorem, a nie słowem kluczowym. Dlatego" select "może być użyte do odniesienia się do kolumny lub tabeli o nazwie" select ", podczas gdy niecytowany wybór byłby traktowany jako słowo kluczowe i dlatego powodowałby błąd analizy, gdy jest używany tam, gdzie oczekiwana jest nazwa tabeli lub kolumny.


48
Ostrzeżenie: bez cudzysłowów PostgreSQL składa wszystkie identyfikatory na małe litery. MyTable, myTableI mytablesą tak samo. Z cudzysłowami to składanie nie jest wykonywane. Więc "MyTable"nie jest już tym samym, co mytable.
AH

19
Jeszcze lepiej, powstrzymaj się od używania słów zastrzeżonych lub mieszanych wielkości liter jako identyfikatorów, a nigdy nie będziesz musiał używać podwójnych cudzysłowów ani otrzymywać dziwnych komunikatów o błędach.
Erwin Brandstetter


8
@ErwinBrandstetter Problem pojawia się, gdy pracujesz nad ustalonym projektem.
ceruleus

5
@ HoàngLong tak, to robi. update "user" set "password" = 'value...';działa doskonale ...
Phill

0

Jeśli nie podajesz cudzysłowów w żadnych polach / kolumnach, zostaną one domyślnie zmniejszone przez Postgres. A Postgres pominie sprawdzanie słowa kluczowego, jeśli chodzi o nazwę kolumny.

W Twoim przypadku nie sądzę, aby dodawanie cytatów było obowiązkowe, jeśli chodzi o rozszerzenie columns. Ale jeśli używasz keywords(zarejestrowany przez PostgreSQL), jak nazwa Table, Schema, Functionlub Triggeretc, należy użyć albo cudzysłowów, można też podać nazwę schematu z kropką konkatenacji.

Załóżmy, że porządek jest słowem kluczowym zarejestrowanym przez Postgres. W niektórych scenariuszach musisz użyć tego słowa kluczowego jako nazwy tabeli.

W tym czasie Postgres pozwoli ci stworzyć tabelę z keywords. Na tym polega piękno Postgres.

Aby uzyskać dostęp do tabeli zamówień, musisz użyć podwójnego cudzysłowu lub możesz podać nazwę schematu przed nazwą tabeli.

NA PRZYKŁAD

1.

select * from schema_name.order;

2.

select * from "order";

Podobnie możesz użyć tego typu kombinacji. Mam nadzieję, że to ci pomoże.


-1

Aby być po bezpiecznej stronie, musisz zbudować instrukcję wstawiania z rozdzielanymi identyfikatorami.

SQL 2003 określa, że ​​rozdzielany identyfikator powinien być umieszczany w cudzysłowie, "a jeśli w identyfikatorze występuje podwójny cudzysłów, należy go zduplikować. Zobacz BNF:

https://ronsavage.github.io/SQL/sql-2003-2.bnf.html#delimited%20identifier

Oto kod do zacytowania identyfikatora:

static String delimited_identifier (String identifier)
{
  return "\"" + identifier.replaceAll ("\"", "\"\"") + "\"";
}

A oto kod do zbudowania insertu:

static String build_insert (String table, String[] columns)
{
  StringBuilder sql = new StringBuilder ();
  StringBuilder values = new StringBuilder ();

  sql.append ("INSERT INTO ");
  sql.append (delimited_identifier (table));
  sql.append (" (");
  int c = 0;
  if (columns.length > 0) {
    sql.append (delimited_identifier (columns[c]));
    values.append ("?");
  }
  for (++c; c < columns.length; c++) {
    sql.append (", ");
    sql.append (delimited_identifier (columns[c]));
    values.append (", ?");
  }
  sql.append (") VALUES (");
  sql.append (values.toString ());
  sql.append (")");

  return sql.toString ();
}

Przykład:

String sql = build_insert ("Person", new String[]{"First name", "Last name"});
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.