sp_describe_first_result_set (Transact-SQL)
gäller för:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
SQL-analysslutpunkt i Microsoft Fabric
Warehouse i Microsoft Fabric
Returnerar metadata för den första möjliga resultatuppsättningen för Transact-SQL batch. Returnerar en tom resultatuppsättning om batchen inte returnerar några resultat. Genererar ett fel om databasmotorn inte kan fastställa metadata för den första frågan som ska köras genom att utföra en statisk analys. Den dynamiska hanteringsvyn sys.dm_exec_describe_first_result_set returnerar samma information.
Transact-SQL syntaxkonventioner
Syntax
sp_describe_first_result_set [ @tsql = ] N'tsql'
[ , [ @params = ] N'@parameter_name data_type [ , ... n ]' ]
[ , [ @browse_information_mode = ] <tinyint> ]
[ ; ]
Argument
Viktig
Argument för utökade lagrade procedurer måste anges i den specifika ordning som beskrivs i avsnittet Syntax. Om parametrarna anges i fel ordning visas ett felmeddelande.
[ @tsql = ] "tsql"
En eller flera Transact-SQL-instruktioner. @tsql kan vara nvarchar(n) eller nvarchar(max).
[ @params = ] N'@parameter_namedata_type [ , ... n ]'
@params innehåller en deklarationssträng för parametrar för Transact-SQL batch, som liknar sp_executesql
. Parametrarna kan vara nvarchar(n) eller nvarchar(max).
En sträng som innehåller definitionerna för alla parametrar som är inbäddade i @tsql. Strängen måste vara antingen en Unicode-konstant eller en Unicode-variabel. Varje parameterdefinition består av ett parameternamn och en datatyp.
n är en platshållare som anger ytterligare parameterdefinitioner. Varje parameter som anges i -instruktionen måste definieras i @params. Om Transact-SQL-instruktionen eller batchen i -instruktionen inte innehåller parametrar krävs inte @params.
NULL
är standardvärdet för den här parametern.
[ @browse_information_mode = ] tinyint
Anger om extra nyckelkolumner och källtabellinformation returneras. Om värdet är inställt på 1
analyseras varje fråga som om den innehåller ett FOR BROWSE
alternativ i frågan.
Om värdet är
0
returneras ingen information.Om värdet är inställt på
1
analyseras varje fråga som om den innehåller ettFOR BROWSE
alternativ i frågan. Detta returnerar bastabellnamn som källkolumninformation.Om värdet är inställt på
2
analyseras varje fråga som om den skulle användas för att förbereda eller köra en markör. Detta returnerar visningsnamn som källkolumninformation.
Returnera kodvärden
sp_describe_first_result_set
returnerar alltid statusen noll vid lyckat resultat. Om proceduren utlöser ett fel och proceduren anropas som en RPC fylls returstatusen i av den typ av fel som beskrivs i kolumnen error_type i sys.dm_exec_describe_first_result_set
. Om proceduren anropas från Transact-SQL är returvärdet alltid noll, även om det finns ett fel.
Resultatuppsättning
Dessa vanliga metadata returneras som en resultatuppsättning med en rad för varje kolumn i resultatmetadata. Varje rad beskriver typen och nullbarheten för kolumnen i det format som beskrivs i följande avsnitt. Om den första instruktionen inte finns för varje kontrollsökväg returneras en resultatuppsättning med noll rader.
Kolumnnamn | Datatyp | Beskrivning |
---|---|---|
is_hidden |
bit | Anger att kolumnen är en extra kolumn som har lagts till i informationssyfte och att den inte visas i resultatuppsättningen. Inte nullbar. |
column_ordinal |
int | Innehåller kolumnens ordningstal i resultatuppsättningen. Den första kolumnens position anges som 1 . Inte nullbar. |
name |
sysname | Innehåller namnet på kolumnen om ett namn kan fastställas. Annars innehåller den NULL . Nullbar. |
is_nullable |
bit | Innehåller värdet 1 om kolumnen tillåter NULL , 0 om kolumnen inte tillåter NULL och 1 om det inte går att avgöra om kolumnen tillåter NULL . Inte nullbar. |
system_type_id |
int | Innehåller system_type_id för kolumnens datatyp enligt sys.types . För CLR-typer, även om kolumnen system_type_name returnerar NULL , returnerar den här kolumnen värdet 240 . Inte nullbar. |
system_type_name |
nvarchar(256) | Innehåller namn och argument (till exempel längd, precision, skala) som angetts för kolumnens datatyp. Om datatypen är en användardefinierad aliastyp anges den underliggande systemtypen här. Om det är en CLR-användardefinierad typ returneras NULL i den här kolumnen. Nullbar. |
max_length |
liten | Maximal längd (i byte) för kolumnen.-1 = Kolumndatatypen är varchar(max), nvarchar(max), varbinary(max)eller xml-.För text kolumner är max_length -värdet 16 eller värdet som anges av sp_tableoption 'text in row' . Inte nullbar. |
precision |
pytteliten | Precision för kolumnen om den är numerisk. Annars returneras 0 . Inte nullbar. |
scale |
pytteliten | Skala av kolumnen om den är numerisk. Annars returneras 0 . Inte nullbar. |
collation_name |
sysname | Namn på sortering av kolumnen om den är teckenbaserad. Annars returneras NULL . Nullbar. |
user_type_id |
int | För CLR- och aliastyper innehåller user_type_id av datatypen för kolumnen enligt beskrivningen i sys.types . Annars är NULL . Nullbar. |
user_type_database |
sysname | För CLR- och aliastyper innehåller namnet på databasen där typen har definierats. Annars är NULL . Nullbar. |
user_type_schema |
sysname | För CLR- och aliastyper innehåller namnet på schemat där typen har definierats. Annars är NULL . Nullbar. |
user_type_name |
sysname | För CLR- och aliastyper innehåller namnet på typen. Annars är NULL . Nullbar. |
assembly_qualified_type_name |
nvarchar(4000) | För CLR-typer returnerar namnet på sammansättningen och klassen som definierar typen. Annars är NULL . Nullbar. |
xml_collection_id |
int | Innehåller xml_collection_id för kolumnens datatyp enligt sys.columns . Den här kolumnen returnerar NULL om den typ som returneras inte är associerad med en XML-schemasamling. Nullbar. |
xml_collection_database |
sysname | Innehåller databasen där XML-schemasamlingen som är associerad med den här typen har definierats. Den här kolumnen returnerar NULL om den typ som returneras inte är associerad med en XML-schemasamling. Nullbar. |
xml_collection_schema |
sysname | Innehåller schemat där XML-schemasamlingen som är associerad med den här typen definieras. Den här kolumnen returnerar NULL om den typ som returneras inte är associerad med en XML-schemasamling. Nullbar. |
xml_collection_name |
sysname | Innehåller namnet på XML-schemasamlingen som är associerad med den här typen. Den här kolumnen returnerar NULL om den typ som returneras inte är associerad med en XML-schemasamling. Nullbar. |
is_xml_document |
bit | Returnerar 1 om den returnerade datatypen är XML och den typen garanterat är ett fullständigt XML-dokument (inklusive en rotnod), i stället för ett XML-fragment. Annars returneras 0 . Inte nullbar. |
is_case_sensitive |
bit | Returnerar 1 om kolumnen är en skiftlägeskänslig strängtyp och 0 om den inte är det. Inte nullbar. |
is_fixed_length_clr_type |
bit | Returnerar 1 om kolumnen är en CLR-typ med fast längd och 0 om den inte är det. Inte nullbar. |
source_server |
sysname | Namnet på den ursprungliga servern som returneras av kolumnen i det här resultatet (om den kommer från en fjärrserver). Namnet anges som det visas i sys.servers . Returnerar NULL om kolumnen kommer från den lokala servern eller om den inte kan fastställas vilken server den kommer från. Fylls bara i om webbinformation begärs. Nullbar. |
source_database |
sysname | Namnet på den ursprungliga databasen som returneras av kolumnen i det här resultatet. Returnerar NULL om databasen inte kan fastställas. Fylls bara i om webbinformation begärs. Nullbar. |
source_schema |
sysname | Namnet på det ursprungliga schemat som returneras av kolumnen i det här resultatet. Returnerar NULL om schemat inte kan fastställas. Fylls bara i om webbinformation begärs. Nullbar. |
source_table |
sysname | Namnet på den ursprungliga tabellen som returneras av kolumnen i det här resultatet. Returnerar NULL om tabellen inte kan fastställas. Fylls bara i om webbinformation begärs. Nullbar. |
source_column |
sysname | Namnet på den ursprungliga kolumnen som returneras av resultatkolumnen. Returnerar NULL om kolumnen inte kan fastställas. Fylls bara i om webbinformation begärs. Nullbar. |
is_identity_column |
bit | Returnerar 1 om kolumnen är en identitetskolumn och 0 om inte. Returnerar NULL om det inte går att fastställa att kolumnen är en identitetskolumn. Nullbar. |
is_part_of_unique_key |
bit | Returnerar 1 om kolumnen ingår i ett unikt index (inklusive unikt och primärt villkor) och 0 om inte. Returnerar NULL om det inte går att fastställa att kolumnen är en del av ett unikt index. Fylls endast i om webbinformation begärs. Nullbar. |
is_updateable |
bit | Returnerar 1 om kolumnen är uppdateringsbar och 0 om inte. Returnerar NULL om det inte går att fastställa att kolumnen kan uppdateras. Nullbar. |
is_computed_column |
bit | Returnerar 1 om kolumnen är en beräknad kolumn och 0 om inte. Returnerar NULL om det inte går att fastställa att kolumnen är en beräknad kolumn. Nullbar. |
is_sparse_column_set |
bit | Returnerar 1 om kolumnen är en gles kolumn och 0 om inte. Returnerar NULL om det inte går att fastställa att kolumnen är en del av en gles kolumnuppsättning. Nullbar. |
ordinal_in_order_by_list |
liten | Positionen för den här kolumnen i ORDER BY lista. Returnerar NULL om kolumnen inte visas i ORDER BY -listan eller om ORDER BY -listan inte kan fastställas unikt. Nullbar. |
order_by_list_length |
liten | Längden på listan över ORDER BY . Returnerar NULL om det inte finns någon ORDER BY lista eller om ORDER BY -listan inte kan fastställas unikt. Det här värdet är detsamma för alla rader som returneras av sp_describe_first_result_set . Nullbar. |
order_by_is_descending |
liten | Om ordinal_in_order_by_list inte är NULL rapporterar kolumnen order_by_is_descending riktningen för ORDER BY -satsen för den här kolumnen. Annars rapporterar den NULL . Nullbar. |
tds_type_id |
int | För internt bruk. Inte nullbar. |
tds_length |
int | För internt bruk. Inte nullbar. |
tds_collation_id |
int | För internt bruk. Nullbar. |
tds_collation_sort_id |
pytteliten | För internt bruk. Nullbar. |
Anmärkningar
sp_describe_first_result_set
garanterar att om proceduren returnerar de första resultatuppsättningsmetadata för (en hypotetisk) batch A och om den batchen (A) sedan körs, så körs batchen antingen:
- genererar ett optimeringstidsfel
- genererar ett körningsfel
- returnerar ingen resultatuppsättning
- returnerar en första resultatuppsättning med samma metadata som beskrivs av
sp_describe_first_result_set
Namn, nullability och datatyp kan skilja sig åt. Om sp_describe_first_result_set
returnerar en tom resultatuppsättning är garantin att batchkörningen returnerar resultatlösa uppsättningar.
Den här garantin förutsätter att det inte finns några relevanta schemaändringar på servern. Relevanta schemaändringar på servern omfattar inte att skapa temporära tabeller eller tabellvariabler i batch A mellan den tid då sp_describe_first_result_set
anropas och den tid då resultatuppsättningen returneras under körningen, inklusive schemaändringar som gjorts av batch B.
sp_describe_first_result_set
returnerar ett fel i något av följande fall:
Indata @tsql är inte en giltig Transact-SQL batch. Giltigheten bestäms genom parsning och analys av Transact-SQL batch. Eventuella fel som orsakas av batchen under frågeoptimeringen eller under körningen beaktas inte när du avgör om Transact-SQL batchen är giltig.
@params är inte
NULL
och innehåller en sträng som inte är en syntaktiskt giltig deklarationssträng för parametrar, eller om den innehåller en sträng som deklarerar en parameter mer än en gång.Indata Transact-SQL batch deklarerar en lokal variabel med samma namn som en parameter som deklareras i @params.
-instruktionen använder en tillfällig tabell.
Frågan innehåller skapandet av en permanent tabell som sedan efterfrågas.
Om alla andra kontroller lyckas beaktas alla möjliga kontrollflödessökvägar i indatabatchen. Detta tar hänsyn till alla kontrollflödesinstruktioner (GOTO
, IF
/ELSE
, WHILE
och Transact-SQL TRY
/CATCH
block) samt alla procedurer, dynamiska Transact-SQL batchar eller utlösare som anropas från indatabatchen av en EXEC
-instruktion, en DDL-instruktion som gör att DDL-utlösare utlöses eller en DML-instruktion som gör att utlösare utlöses på en måltabell eller på en tabell som ändras på grund av en sammanhängande åtgärd i en DML-instruktion villkor för sekundärnyckel. Vid något tillfälle, som med många möjliga kontrollsökvägar, stoppas en algoritm.
För varje kontrollflödessökväg bestäms den första instruktionen (om någon) som returnerar en resultatuppsättning av sp_describe_first_result_set
.
När flera möjliga första instruktioner hittas i en batch kan deras resultat variera i antal kolumner, kolumnnamn, nullabilitet och datatyp. Hur dessa skillnader hanteras beskrivs mer detaljerat här:
Om antalet kolumner skiljer sig åt genereras ett fel och inget resultat returneras.
Om kolumnnamnet skiljer sig åt anges kolumnnamnet som returneras till
NULL
.Om nullbarheten skiljer sig åt tillåter den returnerade nullbarheten
NULL
.Om datatypen skiljer sig åt utlöses ett fel och inget resultat returneras förutom i följande fall:
- varchar(a) till varchar(a') där a" > a.
- varchar(a) till varchar(max)
- nvarchar(a) till nvarchar(a') där a" > a.
- nvarchar(a) till nvarchar(max)
- varbinary(a) till varbinary(a') där a" > a.
- varbinary(a) till varbinary(max)
sp_describe_first_result_set
stöder inte indirekt rekursion.
Behörigheter
Kräver behörighet att köra argumentet @tsql.
Exempel
Vanliga exempel
A. Grundläggande exempel
I följande exempel beskrivs resultatuppsättningen som returneras från en enda fråga.
EXEC sp_describe_first_result_set @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes';
I följande exempel visas resultatuppsättningen som returneras från en enskild fråga som innehåller en parameter.
EXEC sp_describe_first_result_set @tsql = N'
SELECT object_id, name, type_desc
FROM sys.indexes
WHERE object_id = @id1',
@params = N'@id1 int';
B. Exempel på bläddra-läge
Följande tre exempel illustrerar den viktigaste skillnaden mellan de olika b&ingsinformationslägena. Endast relevanta kolumner ingår i frågeresultatet.
Exempel med 0
, som anger att ingen information returneras.
CREATE TABLE dbo.t (
a INT PRIMARY KEY,
b1 INT
);
GO
CREATE VIEW dbo.v AS
SELECT b1 AS b2
FROM dbo.t;
GO
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM dbo.v', NULL, 0;
Här är en partiell resultatuppsättning.
is_hidden | column_ordinal | Namn | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | b3 | NULL |
NULL |
NULL |
NULL |
Exempel med 1 som anger att den returnerar information som om den innehåller ett FOR BROWSE-alternativ i frågan.
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 1;
Här är en partiell resultatuppsättning.
is_hidden | column_ordinal | Namn | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | b3 | Dbo | t | B1 | 0 |
1 |
2 | a | Dbo | t | a | 1 |
Exempel med 2 som anger analyserad som om du förbereder en markör.
EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 2;
Här är resultatuppsättningen.
is_hidden | column_ordinal | Namn | source_schema | source_table | source_column | is_part_of_unique_key |
---|---|---|---|---|---|---|
0 |
1 | B3 | Dbo | v | B2 | 0 |
1 |
2 | ROWSTAT | NULL |
NULL |
NULL |
0 |
C. Store-resultat i en tabell
I vissa scenarier måste du placera resultatet av sp_describe_first_result_set
-proceduren i en tabell så att du kan bearbeta schemat ytterligare.
Först måste du skapa en tabell som matchar utdata från sp_describe_first_result_set
proceduren:
CREATE TABLE #frs (
is_hidden BIT NOT NULL,
column_ordinal INT NOT NULL,
name SYSNAME NULL,
is_nullable BIT NOT NULL,
system_type_id INT NOT NULL,
system_type_name NVARCHAR(256) NULL,
max_length SMALLINT NOT NULL,
precision TINYINT NOT NULL,
scale TINYINT NOT NULL,
collation_name SYSNAME NULL,
user_type_id INT NULL,
user_type_database SYSNAME NULL,
user_type_schema SYSNAME NULL,
user_type_name SYSNAME NULL,
assembly_qualified_type_name NVARCHAR(4000),
xml_collection_id INT NULL,
xml_collection_database SYSNAME NULL,
xml_collection_schema SYSNAME NULL,
xml_collection_name SYSNAME NULL,
is_xml_document BIT NOT NULL,
is_case_sensitive BIT NOT NULL,
is_fixed_length_clr_type BIT NOT NULL,
source_server SYSNAME NULL,
source_database SYSNAME NULL,
source_schema SYSNAME NULL,
source_table SYSNAME NULL,
source_column SYSNAME NULL,
is_identity_column BIT NULL,
is_part_of_unique_key BIT NULL,
is_updateable BIT NULL,
is_computed_column BIT NULL,
is_sparse_column_set BIT NULL,
ordinal_in_order_by_list SMALLINT NULL,
order_by_list_length SMALLINT NULL,
order_by_is_descending SMALLINT NULL,
tds_type_id INT NOT NULL,
tds_length INT NOT NULL,
tds_collation_id INT NULL,
tds_collation_sort_id TINYINT NULL
);
När du skapar en tabell kan du lagra schemat för en fråga i tabellen.
DECLARE @tsql NVARCHAR(MAX) = 'select top 0 * from sys.credentials';
INSERT INTO #frs
EXEC sys.sp_describe_first_result_set @tsql;
SELECT * FROM #frs;
Exempel på problem
I följande exempel används två tabeller för alla exempel. Kör följande instruktioner för att skapa exempeltabellerna.
CREATE TABLE dbo.t1 (
a INT NULL,
b VARCHAR(10) NULL,
c NVARCHAR(10) NULL
);
CREATE TABLE dbo.t2 (
a SMALLINT NOT NULL,
d VARCHAR(20) NOT NULL,
e INT NOT NULL
);
Fel eftersom antalet kolumner skiljer sig åt
Antalet kolumner i möjliga första resultatuppsättningar skiljer sig åt i det här exemplet.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT a FROM t1;
ELSE
SELECT a, b FROM t1;
SELECT * FROM t; -- Ignored, not a possible first result set.';
Fel eftersom datatyperna skiljer sig åt
Kolumntyperna skiljer sig åt i olika möjliga första resultatuppsättningar.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT a FROM t1;
ELSE
SELECT a FROM t2;';
Detta resulterar i ett fel av matchningstyper (int jämfört med smallint).
Det går inte att fastställa kolumnnamnet
Kolumner i möjliga första resultatuppsättningar skiljer sig efter längd för samma variabellängdstyp, nullability och kolumnnamn:
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT d FROM t2;';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
Okänt kolumnnamn |
system_type_name |
varchar |
max_length |
20 |
is_nullable |
1 |
Kolumnnamn som tvingas vara identiskt via alias
Samma som tidigare, men kolumner har samma namn via kolumnalias.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT d AS b FROM t2;';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
b |
system_type_name |
varchar |
max_length |
20 |
is_nullable |
1 |
Fel eftersom kolumntyper inte kan matchas
Kolumntyperna skiljer sig åt i olika möjliga första resultatuppsättningar.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
SELECT b FROM t1;
ELSE
SELECT c FROM t1;';
Detta resulterar i ett fel av matchningstyper (varchar(10) jämfört med nvarchar(10)).
Resultatuppsättningen kan returnera ett fel
Den första resultatuppsättningen är antingen fel eller resultatuppsättning.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
RAISERROR(''Some Error'', 16 , 1);
ELSE
SELECT a FROM t1;
SELECT e FROM t2; -- Ignored, not a possible first result set.';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
Vissa kodsökvägar returnerar inga resultat
Den första resultatuppsättningen är antingen null eller en resultatuppsättning.
EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
RETURN;
SELECT a FROM t1;';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
Resultat från dynamisk SQL
Den första resultatuppsättningen är dynamisk SQL som kan identifieras eftersom det är en literalsträng.
EXEC sp_describe_first_result_set @tsql = N'
EXEC(N''SELECT a FROM t1'');';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
Resultatfel från dynamisk SQL
Den första resultatuppsättningen är odefinierad på grund av dynamisk SQL.
EXEC sp_describe_first_result_set @tsql = N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
SET @SQL += N'' AND e > 10'';
EXEC(@SQL);';
Detta resulterar i ett fel. Resultatet kan inte identifieras på grund av den dynamiska SQL-filen.
Resultatuppsättning som angetts av användaren
Den första resultatuppsättningen anges manuellt av användaren.
EXEC sp_describe_first_result_set @tsql =
N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
SET @SQL += N'' AND e > 10'';
EXEC(@SQL)
WITH RESULT SETS (
(Column1 BIGINT NOT NULL)
);';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
Column1 |
system_type_name |
bigint |
is_nullable |
0 |
Fel som orsakas av en tvetydig resultatuppsättning
Det här exemplet förutsätter att en annan användare med namnet user1
har en tabell med namnet t1
i standardschemat s1
med kolumner (a int NOT NULL
).
EXEC sp_describe_first_result_set @tsql = N'
IF (@p > 0)
EXECUTE AS USER = ''user1'';
SELECT * FROM t1;',
@params = N'@p int';
Den här koden resulterar i ett Invalid object name
fel.
t1
kan vara antingen dbo.t1
eller s1.t1
, var och en med olika antal kolumner.
Resultat även med tvetydig resultatuppsättning
Använd samma antaganden som i föregående exempel.
EXEC sp_describe_first_result_set @tsql =
N'
IF (@p > 0)
EXECUTE AS USER = ''user1'';
SELECT a FROM t1;';
Här är en partiell resultatuppsättning.
Spalt | Värde |
---|---|
name |
a |
system_type_name |
int |
is_nullable |
1 |
Både dbo.t1.a
och s1.t1.a
har typ intoch olika nullabilitet.