Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Извличане на имена на колони и типове на съхранена процедура?

[Току-що разбрах, че съм отговарял на този въпрос преди]

Правенето на това за съхранена процедура е много по-сложно, отколкото за изглед или таблица. Един от проблемите е, че една съхранена процедура може да има множество различни кодови пътища в зависимост от входните параметри и дори неща, които не можете да контролирате като състояние на сървъра, време от деня и т.н. Така например какво бихте очаквали да видите като изход за тази съхранена процедура? Ами ако има множество набори от резултати, независимо от условните?

CREATE PROCEDURE dbo.foo
  @bar INT
AS
BEGIN
  SET NOCOUNT ON;

  IF @bar = 1
    SELECT a, b, c FROM dbo.blat;
  ELSE
    SELECT d, e, f, g, h FROM dbo.splunge;
END
GO

Ако вашата съхранена процедура няма кодови пътища и сте уверени, че винаги ще виждате един и същ набор от резултати (и можете да определите предварително какви стойности трябва да бъдат предоставени, ако съхранената процедура има незадължителни параметри), нека вземем прост пример:

CREATE PROCEDURE dbo.bar
AS
BEGIN
  SET NOCOUNT ON;

  SELECT a = 'a', b = 1, c = GETDATE();
END
GO

FMTONLY

Един от начините е да направите нещо подобно:

SET FMTONLY ON;
GO
EXEC dbo.bar;

Това ще ви даде празен набор от резултати и вашето клиентско приложение може да разгледа свойствата на този набор от резултати, за да определи имената на колони и типове данни.

Сега има много проблеми с SET FMTONLY ON; че няма да навлизам тук, но най-малкото трябва да се отбележи, че тази команда е отхвърлена - по основателна причина. Също така внимавайте да SET FMTONLY OFF; когато сте готови, или ще се чудите защо сте създали съхранена процедура успешно, но след това не можете да я изпълните. И не, не ви предупреждавам за това, защото просто ми се случи. Честен. :-)

ОТКРИВАНЕ

Като създадете свързан сървър с обратна връзка, можете да използвате инструменти като OPENQUERY за да изпълните съхранена процедура, но да върнете композируем набор от резултати (добре, моля, приемете това като изключително хлабава дефиниция), която можете да проверите. Първо създайте loopback сървър (това предполага локален екземпляр с име FOO ):

USE master;
GO
EXEC sp_addlinkedserver @server = N'.\FOO', @srvproduct=N'SQL Server'
GO
EXEC sp_serveroption @server=N'.\FOO', @optname=N'data access', 
  @optvalue=N'true';

Сега можем да вземем процедурата по-горе и да я вкараме в заявка като тази:

SELECT * INTO #t 
FROM OPENQUERY([.\FOO], 'EXEC dbname.dbo.bar;')
WHERE 1 = 0;

SELECT c.name, t.name
FROM tempdb.sys.columns AS c
INNER JOIN sys.types AS t
ON c.system_type_id = t.system_type_id
WHERE c.[object_id] = OBJECT_ID('tempdb..#t');

Това игнорира типове псевдоними (по-рано известни като потребителски дефинирани типове данни) и също така може да покаже два реда за колони, дефинирани като например sysname . Но от горното се получава:

name   name
----   --------
b      int
c      datetime
a      varchar

Очевидно има още работа тук - varchar не показва дължина и ще трябва да получите точност/мащаб за други типове, като datetime2 , time и decimal . Но това е начало.

SQL Server 2012

Има някои нови функции в SQL Server 2012, които правят откриването на метаданни много по-лесно. За горната процедура можем да направим следното:

SELECT name, system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object
(
  OBJECT_ID('dbo.bar'), 
  NULL
);

Наред с други неща, това всъщност осигурява прецизност и мащаб и разрешава типове псевдоними за нас. За горната процедура това дава:

name   system_type_name
----   ----------------
a      varchar(1)
b      int
c      datetime

Няма голяма разлика визуално, но когато започнете да навлизате във всички различни типове данни с различна точност и мащаб, ще оцените допълнителната работа, която тази функция върши за вас.

Недостатъкът:в SQL Server 2012 поне тези функции работят само за първия набор от резултати (както подсказва името на функцията).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SSIS Задача за непоследователно импортиране на броя на колоните?

  2. Грешка в CTE:Типовете не съвпадат между котвата и рекурсивната част

  3. 5 бързи полезни съвети за SQL Server Производствени администраторите на бази данни

  4. Намерете низ, като потърсите всички таблици в SQL Server

  5. OLTP в паметта на SQL Server:Основите