У NULL есть тип?

14

Различные источники (например, Википедия , PSOUG ) утверждают, что у Oracle nullнет типа. Это правда?

А как насчет других РСУБД?

Джек говорит, попробуйте topanswers.xyz
источник

Ответы:

8

Oracle:

У nullлитерала нет типа, но

  1. null может быть приведен к любому типу, и это может быть необходимо, когда

    • вызов перегруженных процедур или функций
    • управление типом возврата decodeфункции, например:

      select decode('A','B',to_char(null),'A','1') from dual;
      DECODE('A','B',TO_CHAR(NULL),'A','1')
      -------------------------------------
      1
      
      select decode('A','B',to_number(null),'A','1') from dual;
      DECODE('A','B',TO_NUMBER(NULL),'A','1')
      --------------------------------------- 
                                            1
    • управление типами столбцов операторов множеств, например, unionкогда первый блок запроса включаетnull
  2. nullзначения, хранящиеся в базе данных, всегда имеют тип:

    create table t(n integer, s varchar(10));
    insert into t values(null, null);
    
    select decode('A','B',n,'A','1') from t; 
    DECODE('A','B',N,'A','1')
    -------------------------
                            1
    
    select decode('A','B',s,'A','1') from t;
    DECODE('A','B',S,'A','1')
    -------------------------
    1
Джек Дуглас
источник
2
+1 Для любопытства давайте попробуем выбрать NULL what_type_is_this из DUAL; Конечно, это не практичный полезный пример, и я еще не пробовал, я научился использовать приведения в таких случаях.
bernd_k
6

SQL Server, int

SELECT NULL AS foo INTO dbo.bar
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'bar'
DROP TABLE dbo.bar

MySQL, двоичный (0)

CREATE TABLE mydb.foo (select NULL AS bar);
EXPLAIN mydb.foo;
DROP TABLE mydb.foo;
ГБН
источник
+1 это очень интересно - я предполагал, что это вызовет ошибку, как это происходит в Oracle
Джек говорит, что попробуйте topanswers.xyz
4
Интересная находка. Однако это показывает, что эти механизмы БД по умолчанию используют тип данных при создании таблиц таким образом, что необязательно, чтобы NULL имел тип в этих двигателях. Например, эта ошибка предполагает, что SQL Server действительно обрабатывает NULL как нетипизированный.
Ник Чаммас
2
@Nick select isnumeric(null)= 0 ... интересно
Фактор Мистик
5

Oracle это в каком-то смысле какой-то строковый тип.

Вот что ADO Reader говорит мне. Вот сценарий Powershell:

[System.Reflection.Assembly]::LoadWithPartialName("System.Data.OracleClient") 
$ConnectionString = "Data Source=myTNS;User ID=myUSER;Password=myPassword" 
$conn=new-object System.Data.OracleClient.OracleConnection 
$conn.ConnectionString=$ConnectionString 
$conn.Open() 
$sql = "Select NULL xx from DUAL"
$cmd=new-object System.Data.OracleClient.OracleCommand($sql,$conn)

$r = $cmd.ExecuteReader()

$r.GetSchemaTable() | % { $_
}        

Что дает

ColumnName               : XX
ColumnOrdinal            : 0
ColumnSize               : 0
NumericPrecision         : 0
NumericScale             : 0
DataType                 : System.String
ProviderType             : 22
IsLong                   : False
AllowDBNull              : True
IsAliased                : 
IsExpression             : 
IsKey                    : 
IsUnique                 : 
BaseSchemaName           : 
BaseTableName            : 
BaseColumnName           : 
ProviderSpecificDataType : System.Data.OracleClient.OracleString

Обратите внимание на строку

ProviderSpecificDataType: System.Data.OracleClient.OracleString

bernd_k
источник
3

Postgres:

create table foo as select null as bar;
WARNING:  column "bar" has type "unknown"
DETAIL:  Proceeding with relation creation anyway.

postgres=> \d foo

 Column |  Type   | Modifiers
--------+---------+-----------
 bar    | unknown |
Джек говорит, попробуйте topanswers.xyz
источник