Инициализируйте переменную с выводом хранимой процедуры в MS SQL Server - PullRequest
1 голос
/ 10 октября 2008

Я создал следующую хранимую процедуру ..

CREATE PROCEDURE [dbo].[UDSPRBHPRIMBUSTYPESTARTUP]
(
  @CODE CHAR(5)
  , @DESC VARCHAR(255) OUTPUT
)
AS
DECLARE @SERVERNAME nvarchar(30)
DECLARE @DBASE nvarchar(30)
DECLARE @SQL nvarchar(2000)

SET @SERVERNAME = 
  Convert(nvarchar,
  (SELECT spData FROM dbSpecificData WHERE spLookup = 'CMSSERVER'))
SET @DBASE = 
  Convert(nvarchar,
  (SELECT spData FROM dbSpecificData WHERE spLookup = 'CMSDBNAME'))

SET @SQL = 
  'SELECT clnt_cat_desc FROM ' + @SERVERNAME + 
  '.' + @DBASE + '.dbo.hbl_clnt_cat WHERE inactive = ''N''
  AND clnt_cat_code = ''' + @CODE + ''''

EXECUTE sp_executeSQL @SQL

RETURN

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

Я хочу использовать вывод этой процедуры в качестве значения в таблице ...

DECLARE @clid BIGINT
DECLARE @fileid BIGINT
DECLARE @myCode CHAR(5)
DECLARE @myDesc VARCHAR(255)
DECLARE @@tempDesc VARCHAR(255)

SET @clid = 1831400022
SET @fileid = 2072551358
SET @myCode = 
  (SELECT _clientPrimBusinessType FROM udbhextclient WHERE clid = @clid)

SET @myDesc = 
  EXEC UDSPRBHPRIMBUSTYPESTARTUP @CODE = @myCode, @DESC = @@tempDesc OUTPUT
----------------------------------------------------------------------------
SELECT
  a.clid
  , b.fileid
  , c.usrfullname AS ClientPartner
  , e.usrfullname AS ClientFeeEarner
  , @myDesc AS ClientPrimaryBusinessType
FROM 
  dbclient a
    INNER JOIN
  dbFile b
    ON
  a.clid = b.clid
    INNER JOIN
  dbuser c
    ON 
  a.feeusrid = c.usrid
    INNER JOIN
  udbhextclient d
    ON
  a.clid = d.clid
    INNER JOIN
  dbuser e
    ON
  d._ClientFeeEarner = e.usrid
WHERE 
  a.clid = @clid
  AND b.fileid = @fileid

Я знаю, что это неправильный синтаксис, но вы можете увидеть, что я пытаюсь достичь, не прибегая к временным таблицам, поскольку это будет означать обслуживание на 30 различных серверах с 3-5 базами данных на каждом.

Smink - опробовал ваше решение и получил следующие результаты ...

Running Smink's Solution

Ответы [ 4 ]

7 голосов
/ 10 октября 2008

Изменить строку:

SET @myDesc = 
  EXEC UDSPRBHPRIMBUSTYPESTARTUP @CODE = @myCode, @DESC = @@tempDesc OUTPUT

до

EXEC UDSPRBHPRIMBUSTYPESTARTUP @CODE = @myCode, @DESC = @tempDesc OUTPUT

И вы пропустили назначение @DESC в хранимой процедуре.

SET @SQL = 
  'SELECT @DESC = clnt_cat_desc FROM ' + @SERVERNAME + 
  '.' + @DBASE + '.dbo.hbl_clnt_cat WHERE inactive = ''N''
  AND clnt_cat_code = ''' + @CODE + ''''

EXECUTE sp_executeSQL @SQL, N'@DESC varchar(255) output', @DESC output

Затем следует использовать @tempDesc при следующем выборе:

SELECT
  a.clid
  , b.fileid
  , c.usrfullname AS ClientPartner
  , e.usrfullname AS ClientFeeEarner
  , @tempDesc AS ClientPrimaryBusinessType

Также ваша хранимая процедура допускает SQL-инъекцию:

SET @SQL = 
  'SELECT clnt_cat_desc 
     FROM ' + QUOTENAME(@SERVERNAME) + '.' + QUOTENAME(@DBASE) + '.dbo.hbl_clnt_cat
    WHERE inactive = ''N''
      AND clnt_cat_code = @CODE'

EXECUTE sp_executeSQL @SQL, N'@CODE CHAR(5)', @CODE

(Обновление: исправлены проблемы с внедрением SQL.)

3 голосов
/ 19 октября 2010

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

0 голосов
/ 10 октября 2008

Если вы не хотите трогать вашу ПРОЦЕДУРУ, вы можете создать ФУНКЦИЮ, которая обернет ее, и использовать эту функцию-обертку в запросах.

0 голосов
/ 10 октября 2008

Вы можете создать функцию (вместо процедуры), которая возвращает таблицу.

CREATE FUNCTION [dbo].[my_function]
(
   @par2     UNIQUEIDENTIFIER, 
   @par2     UNIQUEIDENTIFIER,
   @par3     UNIQUEIDENTIFIER
)
RETURNS @returntable TABLE 
(
   col1 UNIQUEIDENTIFIER,
   col2 NVARCHAR(50),
   col3 NVARCHAR(50)
)
AS
BEGIN
...
END
...