Получить типы данных из произвольного оператора SQL в SQL Server 2008 - PullRequest
3 голосов
/ 01 апреля 2010

Учитывая некоторый произвольный SQL, я хотел бы получить типы данных возвращаемых столбцов. Это утверждение может объединять множество таблиц, представлений, TVF и т. Д. Я знаю, что могу создать представление на основе запроса и получить из него типы данных, надеясь, что есть более быстрый путь. Единственное, о чем я мог думать, - это пишу утилиту .net для запуска SQL и изучения результатов, задаваясь вопросом, есть ли ответ на TSQL.


т.е.

Дано (не реальные таблицы, просто пример)

SELECT p.Name AS PersonName, p.Age, a.Account as AccountName
FROM Person as p
LEFT JOIN Account as a
    ON p.Id = a.OwnerId

Я бы хотел что-то вроде

PersonName: (nvarchar (255), не нуль)

Возраст: (smallInt, not null)

и т.д ...

Ответы [ 2 ]

1 голос
/ 02 апреля 2010
    /*you may have to alias some columns if they are not unique*/
    /*EDIT: added fix for 2byte nchar/nvarchar */
    SELECT top (1)  /*<your query columns here>*/ 
    INTO #tmp99
    /*<rest of your query here>*/


    SELECT 'CREATE TABLE [tablename]('  UNION ALL 
    SELECT CASE WHEN ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) = 1 THEN '' ELSE ',' END 
    + CHAR(13) + '[' + c.name + '] [' + t.name + ']' 
    + CASE WHEN c.system_type_id IN (165,167,173,175) 
           THEN CASE WHEN c.max_length <> -1
                     THEN '(' + CAST(c.max_length AS varchar(7)) + ')' 
                     ELSE '(max)' 
                     END 
           WHEN c.system_type_id IN (231,239) 
           THEN CASE WHEN c.max_length <> -1 
                     THEN '(' + CAST(c.max_length/2 AS varchar(7)) + ')' 
                     ELSE '(max)' END
           ELSE 
               CASE WHEN c.system_type_id IN (41,42,43) 
                    THEN '(' + CAST(c.scale AS varchar(7)) + ')'
                    ELSE
                        CASE WHEN c.system_type_id IN (106,108) 
                             THEN '(' + CAST(c.precisiON AS varchar(7)) + ',' + CAST(c.scale AS varchar(7)) + ')'
                             ELSE ''
                             END 
                    END
           END

    + CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END 

    FROM tempdb.sys.columns c
    JOIN tempdb..sysobjects o ON (c.object_id = o.id)
    JOIN tempdb.sys.types t ON (t.user_type_id = c.user_type_id)
    WHERE o.name LIKE '#tmp99%' 
    UNION ALL SELECT ')' 
    FOR XML PATH('')

    DROP TABLE #tmp99
0 голосов
/ 01 апреля 2010

Я пытался достичь этой цели, но это оказалось слишком сложно. Позвольте мне рассказать, как я подошел к нему. Я взял парсер SQL: http://www.sqlparser.com/download.php и C #. Затем попытался проанализировать текст. Для простых запросов это нормально, но вскоре оно становится слишком компилированным. Идея о представлении выглядит намного проще.

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