2013-03-20 70 views
1

我想創建函數,它使用表名作爲參數。在我搜索時,我需要使用動態sql。我試試這樣的代碼:在sql函數中使用表名作爲參數

CREATE FUNCTION get_column_id 
    (
    @TableName VARCHAR(30), 
    @ColumnName VARCHAR(30), 
    ) 
RETURNS int 
AS 
BEGIN 
IF EXISTS 
    (
    DECLARE @SQL VARCHAR(50) 
    SET @sql = 'SELECT' + @ColumnName + 'FROM' + @TableName + 'WHERE @ColumnName = @ColumnNameValue'; 
    EXEC(@sql) 
    ) 
BEGIN 

但是得到錯誤。有什麼辦法可以解決這個問題嗎?

我嘗試這樣的方式

DECLARE @SQL VARCHAR(50) 
SET @SQL = 'SELECT' + @ColumnName + 'FROM' + @Table + 'WHERE @ColumnName = @ColumnNameValue' 
EXEC(@SQL) 
DECLARE @TableName table (Name VARCHAR(30)) 
INSERT INTO @TableName VALUES (@SQL) 
IF EXISTS 
    (SELECT Name FROM @TableName WHERE Name = @ColumnNameValue) 

使用動態SQL,但得到Invalid use of a side-effecting operator 'EXECUTE STRING' within a function. 有誰知道如何繞過這個限制?

+3

好了,你不能在一個函數的SQL Server – Lamak 2013-03-20 13:41:38

回答

2

的錯誤是字符串的串接這之間缺乏空間,

SET @sql = 'SELECT ' + @ColumnName + ' FROM ' + @TableName + ' WHERE ' + @ColumnName + ' = ' + @ColumnNameValue; 
       --^SPACE HERE  ^^    ^and here 

如果例如列的數據類型爲字符串,你需要用單引號的價值,

SET @sql = 'SELECT ' + @ColumnName + ' FROM ' + @TableName + ' WHERE ' + @ColumnName + ' = ''' + @ColumnNameValue + ''''; 

更新1

您還需要聲明的參數@ColumnNameValue,如

CREATE FUNCTION get_column_id 
(
    @TableName VARCHAR(30), 
    @ColumnName VARCHAR(30), 
    @ColumnNameValue VARCHAR(30) 
) 
+1

上使用動態SQL別忘了提及@ColumnNameValue沒有聲明。 – 2013-03-20 13:36:08

+3

所有的想法都是正確的,但是你不能在SQL SERVER用戶定義函數中使用副作用語句。我認爲他將無法完成他的任務。 – gustavodidomenico 2013-03-20 13:39:06

+0

你爲什麼認爲他的意思是'STORED PROCEDURE'?,這個錯誤很可能就是他想在一個函數上使用動態sql,並且無法 – Lamak 2013-03-20 13:43:43

1

Sql Server中的UDF(用戶定義的函數)必須是確定性的。除了你的語法錯誤,你將無法完成你的任務。

,如果你檢查這篇文章在MSDN上:

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

你可以看到下面的引文:

Deterministic functions always return the same result any time they are called 
with a specific set of input values and given the same state of the database.  

Nondeterministic functions may return different results each time they are 
called with a specific set of input values even if the database state that 
they access remains the same.