2009-10-21 25 views
42

Mam kwerendę SQL, która kwerendy ogromne (jak w setki widoków/tabel z trudnych do odczytania nazw takich jak CMM-CPP-FAP-ADD) bazy danych, których nie potrzebuję i nie chcę zrozumieć. Wynik tego zapytania musi zostać zapisany w tabeli pomostowej w celu podania raportu.Jak mogę zwrócić typy danych SQL z mojego zapytania?

Potrzebuję utworzyć tabelę pomostową, ale z setkami widoków/tabel do przeszukania, aby znaleźć typy danych, które są tutaj reprezentowane, muszę się zastanowić, czy istnieje lepszy sposób na skonstruowanie tej tabeli.

Czy ktoś może doradzić, w jaki sposób mogę użyć dowolnego narzędzia SQL Server 2008 do odgadnięcia źródłowych typów danych w mojej bazie danych SQL 2000?

Jako ogólny przykład, chcę wiedzieć, z kwerendy jak:

SELECT Auth_First_Name, Auth_Last_Name, Auth_Favorite_Number 
FROM Authors 

Zamiast rzeczywistych wyników, chcę wiedzieć, że:

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

nie jestem zainteresowany ograniczenia, naprawdę chcę tylko poznać typy danych.

Odpowiedz

46
select * from information_schema.columns 

może Ci zacząć.

+0

Nieprawidłowa nazwa obiektu „information_schema.columns” – JMP

+3

masz bazę danych SENSITIVE CASE? Jeśli tak, musisz użyć 'SELECT * FROM INFORMATION_SCHEMA.Columns' –

+1

Tak, wielkość liter ma znaczenie. Próbowałem SELECT * FROM INFORMATION_SCHEMA.Columns i otrzymałem ten sam błąd nieprawidłowego obiektu. To jest SQL Server 2000 (8.0.2055), czy INFORMATION_SCHEMA istnieje w tej wersji? – JMP

5

Czy zdołasz odtworzyć odtworzenie tabeli pomostowej od podstaw za każdym razem, gdy wykonywane jest zapytanie? Jeśli więc można użyć SELECT ... INTO składni SQL Server i niech się martwić o tworzeniu tabeli przy użyciu poprawnych typów kolumn itp

SELECT * 
INTO your_staging_table 
FROM enormous_collection_of_views_tables_etc 
+0

Niestety nie jest to możliwe. – JMP

+0

Można również utworzyć tę tabelę przemieszczania tylko po to, aby uzyskać typy danych kolumn, używając tabeli information_schema wskazanej przez erikkallen. – Spidey

+5

@JM: Co powiesz na uruchamianie składni 'SELECT ... INTO ... Z ... WHERE 1 = 0' jako zdarzenia jednorazowego w celu utworzenia atrapy tabeli, a następnie użycie Management Studio do skryptowania tworzenia tabeli SQL dla obojętny stolik? – LukeH

16

Można również użyć ...

SQL_VARIANT_PROPERTY() 

... w przypadkach, gdy nie masz bezpośredniego dostępu do metadanych (np. może to być połączone zapytanie do serwera?).

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

W SQL Server 2005 i poza jesteś lepiej wyłączyć za pomocą poglądy katalog (sys.columns), w przeciwieństwie do INFORMATION_SCHEMA. O ile przenośność na inne platformy nie jest ważna. Należy pamiętać, że widoki INFORMATION_SCHEMA nie ulegną zmianie, dlatego stopniowo będą brakować informacji o nowych funkcjach itp. W kolejnych wersjach SQL Server.

+0

To nie będzie działać dla pól tekstowych. Rzucę ten wyjątek: "Zderzenie typu operand: tekst jest niekompatybilny z sql_variant" – eflles

+1

@flles Dzięki, pamiętaj, że jest to wyjątkowy przypadek (kiedy nie masz dostępu do metadanych), a nawet w 2009 roku, kiedy pojawiło się to pytanie, powinieneś zrezygnować z 'text',' ntext' i 'image'. Jeśli ludzie nadal używają tych elementów, to tylko niewielka część ich problemów ... –

0
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME='yourTable'; 
18

Można również wstawić wyniki (lub 10 najlepszych wyników) do tabeli temp i uzyskać kolumny z tabeli temp (tak długo, jak nazwy kolumn są różne).

SELECT TOP 10 * 
INTO #TempTable 
FROM <DataSource> 

Następnie użyj:

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

lub

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

ekstrapolować z Aaron's answer here.

5
SELECT COLUMN_NAME, 
     DATA_TYPE, 
     CHARACTER_MAXIMUM_LENGTH 
FROM information_schema.columns 
WHERE TABLE_NAME = 'YOUR_TABLE_NAME' 

Możesz użyć aliasów kolumn dla lepszego wyglądu.

8

Tam MUSI być łatwiejszy sposób to zrobić ... Niski i oto jest ...!

"sp_describe_first_result_set" to Twój przyjaciel!

Teraz zdaję sobie sprawę, że pytanie zostało zadane specjalnie dla SQL Server 2000, ale szukałem podobnego rozwiązania dla późniejszych wersji i odkryłem pewne natywne wsparcie w SQL, aby to osiągnąć.

W SQL Server 2012 r. Dalej cf. „Sp_describe_first_result_set” - Link to BOL

ja już wdrożył rozwiązanie stosując technikę podobną do @Trisped's powyżej rozerwał ją wdrożyć realizację natywnego SQL Server.

W przypadku, gdy nie jesteśmy na SQL Server 2012 lub SQL Azure Database jeszcze tutaj jest przechowywana proc stworzyłem dla pre-2012 ery baz danych:

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 
1

To da ci wszystko właściwość kolumny związane.

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; 
2

Dla SQL Server 2012 i nowszych: Jeśli to zapytanie do łańcucha wtedy można uzyskać wynik zestaw typów danych tak: Do

DECLARE @query nvarchar(max) = 'select 12.1/10.1 AS [Column1]'; 
EXEC sp_describe_first_result_set @query, null, 0; 
Powiązane problemy