Ответ 1
select * from information_schema.columns
может начать работу.
У меня есть 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
Мне не нужны ограничения, я просто хочу знать типы данных.
select * from information_schema.columns
может начать работу.
Вы также можете вставить результаты (или 10 лучших результатов) в таблицу temp и получить столбцы из таблицы temp (до тех пор, пока имена столбцов будут разными).
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');
Экстраполирован из Аарон ответьте здесь.
Вы также можете использовать...
SQL_VARIANT_PROPERTY()
... в случаях, когда у вас нет прямого доступа к метаданным (например, связанный серверный запрос, возможно?).
http://msdn.microsoft.com/en-us/library/ms178550.aspx
В SQL Server 2005 и выше вам лучше использовать представления каталога (sys.columns), а не INFORMATION_SCHEMA. Если важна переносимость других платформ. Просто имейте в виду, что представления INFORMATION_SCHEMA не будут меняться, и поэтому в последующих версиях SQL Server они не будут получать информацию о новых функциях и т.д.
Должен быть более простой способ сделать это... Низкий, и вот, есть...!
" sp_describe_first_result_set " - ваш друг!
Теперь я понимаю, что вопрос был задан специально для SQL Server 2000, но я искал подобное решение для более поздних версий и обнаружил некоторую встроенную поддержку в SQL для достижения этой цели.
В SQL Server 2012 и далее см. "sp_describe_first_result_set" - ссылка на BOL
Я уже реализовал решение, используя технику, аналогичную описанной выше в @Trisped, и разорвал его для реализации собственной реализации 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
Для SQL Server 2012 и выше: если вы поместите запрос в строку, вы можете получить такие типы данных набора результатов следующим образом:
DECLARE @query nvarchar(max) = 'select 12.1 / 10.1 AS [Column1]';
EXEC sp_describe_first_result_set @query, null, 0;
SELECT COLUMN_NAME,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'
Вы можете использовать псевдонимы столбцов для лучшего вывода.
Можете ли вы уйти с воссозданием промежуточной таблицы с нуля каждый раз, когда выполняется запрос? Если это так, вы можете использовать SELECT ... INTO
синтаксис и позволить SQL Server беспокоиться о создании таблицы с использованием правильных типов столбцов и т.д.
SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME='yourTable';
Это даст вам все свойства, связанные с столбцом.
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;
sp_describe_first_result_set
поможет определить типы данных запроса путем анализа типов данных первого набора результатов запроса
Я использую простое утверждение для отображения результатов, которые можно использовать в документах технической спецификации. Этот пример не содержит всех условий, с которыми вы столкнетесь при работе с базой данных, но дает вам хороший шаблон для работы.
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