Как мне вернуть типы данных SQL из моего запроса? - PullRequest
56 голосов
/ 21 октября 2009

У меня есть SQL-запрос, который запрашивает огромную (например, сотни представлений / таблиц с трудно читаемыми именами, такими как CMM-CPP-FAP-ADD) базу данных, в которой я не нуждаюсь и не хочу ее понимать. Результат этого запроса должен быть сохранен в промежуточной таблице для подачи отчета.

Мне нужно создать промежуточную таблицу, но с сотнями представлений / таблиц, которые нужно просмотреть, чтобы найти типы данных, которые здесь представлены, мне интересно, есть ли лучший способ построить эту таблицу.

Кто-нибудь может посоветовать, как использовать любые инструменты SQL Server 2008 для определения типов исходных данных в моей базе данных SQL 2000?

В качестве общего примера я хочу узнать из запроса:

SELECT Auth_First_Name, Auth_Last_Name, Auth_Favorite_Number 
FROM Authors

Вместо фактических результатов я хочу знать, что:

Auth_First_Name is char(25)
Auth_Last_Name is char(50)
Auth_Favorite_Number is int

Меня не интересуют ограничения, я просто хочу знать типы данных.

Ответы [ 11 ]

54 голосов
/ 21 октября 2009
select * from information_schema.columns

может помочь вам начать.

24 голосов
/ 27 сентября 2014

Вы также можете вставить результаты (или первые 10 результатов) во временную таблицу и получить столбцы из временной таблицы (при условии, что имена столбцов все разные).

SELECT TOP 10 *
INTO #TempTable
FROM <DataSource>

Тогда используйте:

EXEC tempdb.dbo.sp_help N'#TempTable';

или

SELECT * 
FROM tempdb.sys.columns 
WHERE [object_id] = OBJECT_ID(N'tempdb..#TempTable');

Извлечено из Ответ Аарона здесь .

21 голосов
/ 21 октября 2009

Вы также можете использовать ...

SQL_VARIANT_PROPERTY()

... в тех случаях, когда у вас нет прямого доступа к метаданным (например, может быть, запрос на связанный сервер?).

http://msdn.microsoft.com/en-us/library/ms178550.aspx

В SQL Server 2005 и более поздних версиях лучше использовать представления каталога (sys.columns), а не INFORMATION_SCHEMA. Если важна переносимость на другие платформы. Просто помните, что представления INFORMATION_SCHEMA не изменятся, и поэтому в последующих версиях SQL Server им будет постоянно не хватать информации о новых функциях и т. Д.

15 голосов
/ 29 августа 2016

Там ДОЛЖЕН быть более простым способом сделать это ... Низкий и вот, есть ...!

" sp_describe_first_result_set " - ваш друг!

Теперь я понимаю, что вопрос был задан специально для SQL Server 2000, но я искал подобное решение для более поздних версий и обнаружил некоторую встроенную поддержку в SQL для достижения этой цели.

В SQL Server 2012 и далее см. "sp_describe_first_result_set" - Ссылка на BOL

Я уже реализовал решение, используя технику, аналогичную @ Trisped's выше, и извлек его для реализации собственной реализации SQL Server.

Если вы еще не используете SQL Server 2012 или базу данных SQL Azure, вот хранимый процесс, который я создал для баз данных до 2012 года:

CREATE PROCEDURE [fn].[GetQueryResultMetadata] 
    @queryText VARCHAR(MAX)
AS
BEGIN

    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    --SET NOCOUNT ON;

    PRINT @queryText;

    DECLARE
                @sqlToExec NVARCHAR(MAX) = 
                    'SELECT TOP 1 * INTO #QueryMetadata FROM ('
                    +
                    @queryText
                    +
                    ') T;'
                    + '
                        SELECT
                                    C.Name                          [ColumnName],
                                    TP.Name                         [ColumnType],
                                    C.max_length                    [MaxLength],
                                    C.[precision]                   [Precision],
                                    C.[scale]                       [Scale],
                                    C.[is_nullable]                 IsNullable
                        FROM
                                    tempdb.sys.columns              C
                                        INNER JOIN
                                    tempdb.sys.types                TP
                                                                                ON
                                                                                        TP.system_type_id = C.system_type_id
                                                                                            AND
                                                                                        -- exclude custom types
                                                                                        TP.system_type_id = TP.user_type_id
                        WHERE
                                    [object_id] = OBJECT_ID(N''tempdb..#QueryMetadata'');
            '

    EXEC sp_executesql @sqlToExec

END
12 голосов
/ 22 сентября 2017

Для SQL Server 2012 и более поздних версий: если поместить запрос в строку, вы можете получить типы данных результирующего набора, например, так:

DECLARE @query nvarchar(max) = 'select 12.1 / 10.1 AS [Column1]';
EXEC sp_describe_first_result_set @query, null, 0;  
7 голосов
/ 15 декабря 2014
SELECT COLUMN_NAME,
       DATA_TYPE,
       CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'

Вы можете использовать псевдонимы столбцов для лучшего вида вывода.

6 голосов
/ 21 октября 2009

Можете ли вы с легкостью воссоздавать промежуточную таблицу с нуля при каждом выполнении запроса? Если это так, вы можете использовать синтаксис SELECT ... INTO и позволить SQL Server беспокоиться о создании таблицы с использованием правильных типов столбцов и т. Д.

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc
1 голос
/ 19 июня 2019

Я использую простую инструкцию для отображения результатов, которые я могу использовать в технических спецификациях. Этот пример не содержит всех условий, с которыми вы столкнетесь при работе с базой данных, но дает вам хороший шаблон для работы.

SELECT
     TABLE_NAME          AS 'Table Name',
     COLUMN_NAME         AS 'Column Name',
     CASE WHEN DATA_TYPE LIKE '%char'
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, CHARACTER_MAXIMUM_LENGTH) + ')'
          WHEN DATA_TYPE IN ('bit', 'int', 'smallint', 'date')
          THEN DATA_TYPE
          WHEN DATA_TYPE = 'datetime'
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, DATETIME_PRECISION) + ')'
          WHEN DATA_TYPE = 'float'
          THEN DATA_TYPE
          WHEN DATA_TYPE IN ('numeric', 'money')
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, NUMERIC_PRECISION) + ', ' + CONVERT(VARCHAR, NUMERIC_PRECISION_RADIX) + ')'
     END                 AS 'Data Type',
     CASE WHEN IS_NULLABLE = 'NO'
          THEN 'NOT NULL'
          ELSE 'NULL'
     END                 AS 'PK/LK/NOT NULL'
FROM INFORMATION_SCHEMA.COLUMNS 
ORDER BY 
     TABLE_NAME, ORDINAL_POSITION
1 голос
/ 11 января 2019

sp_describe_first_result_set

поможет идентифицировать типы данных запроса путем анализа типов данных первого набора результатов запроса

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql?view=sql-server-2017

1 голос
/ 16 марта 2017

Это даст вам все, что связано со свойством столбца.

SELECT * INTO TMP1
FROM ( SELECT TOP 1 /* rest of your query expression here */ );

SELECT o.name AS obj_name, TYPE_NAME(c.user_type_id) AS type_name, c.*  
FROM sys.objects AS o   
JOIN sys.columns AS c  ON o.object_id = c.object_id  
WHERE o.name = 'TMP1';

DROP TABLE TMP1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...