PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Поведение на NOT LIKE със стойности NULL

Относно NULL

'anything' NOT LIKE NULL дава NULL , а не TRUE .
И само TRUE отговаря на изискванията за филтриращи изрази в WHERE клауза.

Повечето функции връщат NULL на NULL въвеждане (има изключения). Това е естеството на NULL в всяко правилна RDBMS.

Ако желаете единична израз, вие можете използвайте:

AND   (column_default LIKE 'nextval%')  IS NOT TRUE;

Това обаче едва ли е по-кратко или по-бързо. Подробности в ръководството.

Правилна заявка

Вашето запитване все още е ненадеждно. Само име на таблица не е уникално в база данни на Postgres, трябва да посочите името на схемата в допълнение или да разчитате на текущия search_path за да намерите първото съвпадение в него:

Свързано:

  • Как search_path влияе върху разделителната способност на идентификатора и „текущата схема“
SELECT column_name
FROM   information_schema.columns
WHERE  table_name = 'hstore1'
AND    table_schema = 'public'   -- your schema
AND   (column_default IS NULL OR
       column_default NOT LIKE 'nextval%');

По-добре, но все още не е устойчив на куршуми. Колоната по подразбиране, започваща с 'nextval', не прави serial , още. Вижте:

  • Колона на таблицата с автоматично увеличение

За да сте сигурни, проверете дали използваната последователност е "притежавана" от колоната с pg_get_serial_sequence(table_name, column_name) .

Аз лично рядко използвам информационната схема. Тези бавни, раздути изгледи гарантират преносимост между основните версии - и целят преносимост към други съвместими със стандарта RDBMS. Но твърде много е несъвместимо така или иначе. Oracle дори не прилага информационната схема (от 2015 г.).

Също така, полезни колони, специфични за Postgres, липсват в информационната схема. За този случай бих могъл да потърся системните каталози по следния начин:

SELECT *
FROM   pg_catalog.pg_attribute a
WHERE  attrelid = 'table1'::regclass
AND    NOT attisdropped   -- no dropped (dead) columns
AND    attnum > 0         -- no system columns
AND   NOT EXISTS (
   SELECT FROM pg_catalog.pg_attrdef d
   WHERE  (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
   AND    d.adsrc LIKE 'nextval%'
   AND    pg_get_serial_sequence(a.attrelid::regclass::text, a.attname) <> ''
   );

По-бърз и по-надежден, но по-малко преносим.

Ръководството:

Каталогът pg_attrdef съхранява стойностите на колоната по подразбиране. Основната информация за колоните се съхранява в pg_attribute (виж отдолу). Само колоните, които изрично определят стойност по подразбиране (когато таблицата е създадена или колоната се добавя), ще имат запис тук.

'table1'::regclass използва search_path за разрешаване на името, което избягва двусмислието. Можете да квалифицирате по схема името, което да отмените:'myschema.table1'::regclass .

Свързано:

  • Намерете посоченото име на таблица, като използвате име на таблица, поле и схема
  • Вземете ли стойностите по подразбиране на колоните на таблицата в Postgres?


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL:Заявката няма дестинация за данни за резултатите

  2. ГРЕШКА:не можа да се зареди библиотеката “/opt/PostgreSQL/9.0/lib/postgresql/plperl.so”:libperl.so:

  3. Postgresql:Скриптове за изпълнение на psql с парола

  4. foreach %dopar% + RPostgreSQL

  5. Избройте всички последователности в Postgres db 8.1 с SQL