Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

4 modi per scoprire quali colonne verranno restituite da una stored procedure in SQL Server

Se ti trovi mai nella situazione in cui stai per eseguire una procedura memorizzata, ma all'improvviso ti ritrovi. Ti chiedi "Quante colonne restituisce questa cosa? Quali tavoli? Interroga un server remoto?"

La buona notizia è che esistono diversi modi per ottenere queste informazioni prima di eseguire la query. Diamo un'occhiata a loro.

Il sys.dm_exec_describe_first_result_set_for_object Funzione

La prima tappa è il sys.dm_exec_describe_first_result_set_for_object funzione di gestione dinamica del sistema.

Questa funzione accetta un @object_id come parametro e descrive i primi metadati del risultato per il modulo con quell'ID.

Può essere utilizzato su stored procedure e trigger.

Ecco un esempio da dimostrare. In questo caso, utilizzo OBJECT_ID() funzione per restituire l'ID della procedura memorizzata (che mi evita di dover conoscere l'ID effettivo).

SELECT * 
FROM sys.dm_exec_describe_first_result_set_for_object(
    OBJECT_ID('spAlbumsFromArtist'), 
    0
    );  

Risultato:

+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
| is_hidden   | column_ordinal   | name        | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | error_number   | error_severity   | error_state   | error_message   | error_type   | error_type_desc   |
|-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------|
| 0           | 1                | AlbumName   | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | NULL              | NULL            | NULL           | NULL            | 0                    | NULL                    | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 0           | 2                | ReleaseDate | 0             | 40               | date               | 3            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | NULL            | NULL              | NULL            | NULL           | NULL            | 0                    | NULL                    | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+

Se scorri abbastanza lateralmente, vedrai che il source_server , source_database , source_schema , source_table e source_column le colonne sono NULL . Questo perché abbiamo usato 0 come terzo argomento.

Cambiare il terzo argomento in 1 restituirà informazioni sulle tabelle di base a cui si fa riferimento nella procedura memorizzata.

SELECT * 
FROM sys.dm_exec_describe_first_result_set_for_object(
    OBJECT_ID('spAlbumsFromArtist'), 
    1
    );  

Risultato:

+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
| is_hidden   | column_ordinal   | name        | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | error_number   | error_severity   | error_state   | error_message   | error_type   | error_type_desc   |
|-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------|
| 0           | 1                | AlbumName   | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumName       | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 0           | 2                | ReleaseDate | 0             | 40               | date               | 3            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | ReleaseDate     | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 3                | AlbumId     | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumId         | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 4                | ArtistId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Artists        | ArtistId        | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+

Ora, quando scorriamo lateralmente, possiamo vedere che il source_server , source_database , source_schema , source_table e source_column le colonne contengono tutte valori.

In questo caso, la procedura interroga le tabelle su un server collegato chiamato "Homer".

Noterai anche che ora vengono restituite quattro righe, anziché solo due che sono state restituite quando impostiamo il terzo argomento su 0 . Le due righe aggiuntive riflettono le colonne sottostanti che vengono interrogate all'interno della stored procedure.

Ecco la definizione della stored procedure:

CREATE PROCEDURE [dbo].[spAlbumsFromArtist] 
	@ArtistName varchar(255)
AS
	SELECT AlbumName, ReleaseDate
	FROM Homer.Music.dbo.Albums al
		INNER JOIN Homer.Music.dbo.Artists ar
		ON al.ArtistId = ar.ArtistId 
	WHERE ar.ArtistName = @ArtistName;

Quindi, anche se la procedura restituisce solo due colonne, deve fare riferimento ad altre colonne per completare il suo compito.

Guarda come sys.dm_exec_describe_first_result_set_for_object Funziona per altri esempi.

Il sys.dm_exec_describe_first_result_set Visualizza

Questa vista utilizza lo stesso algoritmo della vista precedente e restituisce le stesse informazioni. La differenza è che analizza un batch T-SQL, piuttosto che la procedura memorizzata effettiva.

Ciò significa che puoi usare questa visualizzazione per analizzare il codice che non è necessariamente in una stored procedure o in un trigger. Ad esempio, puoi utilizzarlo per analizzare una vista o una query ad hoc.

Ma questo articolo riguarda l'analisi delle stored procedure, quindi ecco un esempio di come farlo.

SELECT * 
FROM sys.dm_exec_describe_first_result_set(
    'EXEC spAlbumsFromArtist @ArtistId = ''Iron Maiden''',
    null,
    1
    );

Risultato:

+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+
| is_hidden   | column_ordinal   | name        | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | error_number   | error_severity   | error_state   | error_message   | error_type   | error_type_desc   |
|-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------|
| 0           | 1                | AlbumName   | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumName       | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 0           | 2                | ReleaseDate | 0             | 40               | date               | 3            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | ReleaseDate     | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 3                | AlbumId     | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumId         | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
| 1           | 4                | ArtistId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Artists        | ArtistId        | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | NULL           | NULL             | NULL          | NULL            | NULL         | NULL              |
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+----------------+------------------+---------------+-----------------+--------------+-------------------+

Vedi come sys.dm_exec_describe_first_result_set Funziona per altri esempi.

Il sp_describe_first_result_set Procedura memorizzata di sistema

Il sp_describe_first_result_set la procedura memorizzata di sistema fa la stessa cosa (e usa lo stesso algoritmo). Accetta un batch T-SQL e restituisce i metadati per il primo possibile set di risultati.

EXEC sp_describe_first_result_set 
    @tsql = N'EXEC spAlbumsFromArtist @ArtistId = ''Iron Maiden''',
    @params = null,
    @browse_information_mode = 1;

Risultato:

+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+
| is_hidden   | column_ordinal   | name        | is_nullable   | system_type_id   | system_type_name   | max_length   | precision   | scale   | collation_name               | user_type_id   | user_type_database   | user_type_schema   | user_type_name   | assembly_qualified_type_name   | xml_collection_id   | xml_collection_database   | xml_collection_schema   | xml_collection_name   | is_xml_document   | is_case_sensitive   | is_fixed_length_clr_type   | source_server   | source_database   | source_schema   | source_table   | source_column   | is_identity_column   | is_part_of_unique_key   | is_updateable   | is_computed_column   | is_sparse_column_set   | ordinal_in_order_by_list   | order_by_is_descending   | order_by_list_length   | tds_type_id   | tds_length   | tds_collation_id   | tds_collation_sort_id   |
|-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------|
| 0           | 1                | AlbumName   | 0             | 231              | nvarchar(255)      | 510          | 0           | 0       | SQL_Latin1_General_CP1_CI_AS | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumName       | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 231           | 510          | 13632521           | 52                      |
| 0           | 2                | ReleaseDate | 0             | 40               | date               | 3            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | ReleaseDate     | 0                    | 0                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 40            | 3            | NULL               | NULL                    |
| 1           | 3                | AlbumId     | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Albums         | AlbumId         | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 56            | 4            | NULL               | NULL                    |
| 1           | 4                | ArtistId    | 0             | 56               | int                | 4            | 10          | 0       | NULL                         | NULL           | NULL                 | NULL               | NULL             | NULL                           | NULL                | NULL                      | NULL                    | NULL                  | 0                 | 0                   | 0                          | Homer           | Music             | dbo             | Artists        | ArtistId        | 0                    | 1                       | 1               | 0                    | 0                      | NULL                       | NULL                     | NULL                   | 56            | 4            | NULL               | NULL                    |
+-------------+------------------+-------------+---------------+------------------+--------------------+--------------+-------------+---------+------------------------------+----------------+----------------------+--------------------+------------------+--------------------------------+---------------------+---------------------------+-------------------------+-----------------------+-------------------+---------------------+----------------------------+-----------------+-------------------+-----------------+----------------+-----------------+----------------------+-------------------------+-----------------+----------------------+------------------------+----------------------------+--------------------------+------------------------+---------------+--------------+--------------------+-------------------------+

Vedi come sp_describe_first_result_set Funziona per altri esempi.

OPENROWSET con una tabella temporanea

Un'altra opzione è costruire una query che metta i primi zero risultati di un OPENROWSET interrogare in una tabella temporanea, quindi utilizzare una procedura come sp_columns per restituire le informazioni sulla colonna su quella tabella temporanea (che contiene i dati del nostro set di risultati).

Ciò fornirà quindi dettagli, come nomi di colonne, tipi di dati, ecc.

SELECT TOP 0 * INTO #TempTable 
FROM OPENROWSET(
    'SQLNCLI', 
    'Server=localhost;Trusted_Connection=yes;', 
    'EXEC Test.dbo.sp_BadDogs');
EXEC('USE tempdb EXEC sp_columns #TempTable DROP TABLE #TempTable');

Risultato:

+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+
| TABLE_QUALIFIER   | TABLE_OWNER   | TABLE_NAME                                                                                                                       | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | RADIX   | NULLABLE   | REMARKS   | COLUMN_DEF   | SQL_DATA_TYPE   | SQL_DATETIME_SUB   | CHAR_OCTET_LENGTH   | ORDINAL_POSITION   | IS_NULLABLE   | SS_DATA_TYPE   |
|-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------|
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________000000000017 | DogId         | 4           | int         | 10          | 4        | 0       | 10      | 0          | NULL      | NULL         | 4               | NULL               | NULL                | 1                  | NO            | 56             |
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________000000000017 | DogName       | -9          | nvarchar    | 255         | 510      | NULL    | NULL    | 1          | NULL      | NULL         | -9              | NULL               | 510                 | 2                  | YES           | 39             |
| tempdb            | dbo           | #TempTable__________________________________________________________________________________________________________000000000017 | GoodDog       | -7          | bit         | 1           | 1        | NULL    | NULL    | 1          | NULL      | NULL         | -7              | NULL               | NULL                | 3                  | YES           | 50             |
+-------------------+---------------+----------------------------------------------------------------------------------------------------------------------------------+---------------+-------------+-------------+-------------+----------+---------+---------+------------+-----------+--------------+-----------------+--------------------+---------------------+--------------------+---------------+----------------+

Usando questo metodo, puoi anche fare cose come scambiare sp_columns per sp_help o simili.