2009-07-01 58 views

回答

4

要麼您需要修改您的存儲過程爲用戶定義的功能或其他方式。

實現目標的一種粗略方法是在批處理腳本中使用exec語句,並從函數中調用該批處理腳本。類似這樣的:

create function <functionName> 
exec master.sys.xp_cmpshell 'C:\storedProc.bat' 
.... 
.... 

return @return 
end 

更多關於xp_cmpshell on MSDN

1

不能從函數中調用定期存儲的特效 - 唯一的其他函數或一些擴展存儲過程。看到這裏的BOL article(來自SQL 2005)。嘗試從UDF調用標準存儲過程將導致以下錯誤...

消息557,級別16,狀態2,行1 只有函數和一些擴展存儲過程可以在函數內執行。

0

我最近有一個類似的問題。事實上的格式不正確的錯誤消息,因爲sp_executesql的擴展存儲過程,你可以通過下面的腳本檢查: select objectproperty(object_id('sp_executesql'),'IsExtendedProc')

回報1

既然我們不能用sp_executesql即使它是一個XP,我必須使用sp_OAMethod找到另一種解決方法。我的方案是如何根據某些條件(在我的方案中爲null值)在表中動態查找行數。使用sp_OAMethod我建了以下功能:

IF object_id(N'dbo.fc_ContaRegistros_x_Criterio') is not null DROP FUNCTION [dbo].[fc_ContaRegistros_x_Criterio] 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 
CREATE FUNCTION dbo.fc_ContaRegistros_x_Criterio (
    @str_TBName VARCHAR(100), 
    @str_Criter VARCHAR(500) 
) 
RETURNS BIGINT 
AS 
BEGIN 
-- Objetivo : Contar numero de registros de uma determinada tabela de acordo com o critério passado 
-- Criação : Josué Monteiro Viana - 09/07/09 
/* 
Exemplo: 
    DECLARE @count INT 
    SET @count = dbo.fc_ContaRegistros_x_Criterio('master.dbo.sysobjects', '') 
    PRINT @count 
    SET @count = dbo.fc_ContaRegistros_x_Criterio('crk.dbo.acao', 'where cod_acao is null') 
    PRINT @count 
*/ 
    DECLARE 
     @int_objSQL INT, 
     @int_erros INT, 
     @int_objSelectCountResult INT, 
     @bint_SelectCount BIGINT, 
     @sql NVARCHAR(2000) 

    EXEC @int_erros = sp_OACreate 'SQLDMO.SQLServer', @int_objSQL OUTPUT 
    EXEC @int_erros = sp_OASetProperty @int_objSQL, 'LoginSecure', TRUE 
    EXEC @int_erros = sp_OAMethod @int_objSQL, 'Connect', null, '.' 
    --SET @sql = 'SELECT count(*) FROM ' + @str_TBName + ' WHERE ' + @str_Criter 
    SET @sql = 'SELECT count(*) FROM ' + @str_TBName + ' ' + @str_Criter 
    SET @sql = 'ExecuteWithResults("' + @sql + '")' 
    EXEC @int_erros = sp_OAMethod @int_objSQL, @sql, @int_objSelectCountResult OUTPUT 
    EXEC @int_erros = sp_OAMethod @int_objSelectCountResult, 'GetRangeString(1, 1)', @bint_SelectCount OUT 
    EXEC @int_erros = sp_OADestroy @int_objSQL 
    -- debug info: not valid inside a fc 
    --if @int_erros <> 0 EXEC sp_OAGetErrorInfo @int_objSQL else print 'ok' 
    if @int_erros <> 0 SET @bint_SelectCount = @int_erros 
    RETURN @bint_SelectCount 
END 
GO 
SET QUOTED_IDENTIFIER OFF 
GO 
SET ANSI_NULLS ON 
GO 

我知道你的情況有點不同,但我敢肯定,你可以使用這個UDF作爲指導來幫助你。

祝福, Josue Monteiro Viana

相關問題