我想用一個用戶定義的表型別的資料創建一個表@tablename,但我得到的錯誤是 必須宣告表的變數"@tablename">>。
ALTER PROCEDURE [dbo]. [Prod_EntTable]
@paramEntTable typeTableEnt readonly,
@userid int
AS
BEGIN
Declare @tablename nvarchar(20)
Set @tablename ='mynewtable' @userid
SELECT EntID, Title INTO @tablename FROM @paramEntTable
END
我嘗試用EXEC作為
EXEC(N'SELECT EntID, Title INTO mynewtable' @userid ' FROM ' @paramEntTable)
錯誤是<<必須宣告表變數"@paramEntTable">>。 我有什么辦法嗎?謝謝你的幫助
uj5u.com熱心網友回復:
你想每次都根據輸入的@userid創建一個新表。這個場景需要動態的TSQL來執行,我們不能在字串中連接型別引數,所以這對我來說是不可能的。
uj5u.com熱心網友回復:
首先,我需要重復評論中所說的,你想在這里做的整個想法是一個設計缺陷。為每個用戶創建一個表是錯誤的;它從根本上破壞了基本的設計規則。每個用戶都不應該有自己的表,相反,你應該有一個表,它有一個UserID列。然后當您需要某個特定用戶的資料時,您可以使用WHERE來過濾該資料。
如果您的目標是阻止用戶訪問其他用戶的資料,那么請使用行級安全(RLS)來確保用戶只能訪問他們應該訪問的行。
既然如此,你可以實作你想要的東西,但首先要解釋為什么你所擁有的東西不起作用。
-
這將會出錯,因為Set @tablename ='mynewtable' @userid@userid是一個int,而'mynewtable'顯然是一個字面的varchar。因此,'mynewtable'將被隱式投遞到一個int,你會得到以下錯誤。當把varchar值'mynewtable'轉換為資料型別int時,轉換失敗。
-
SQL不是腳本語言,你不能用變數來代替字面意思。上面的內容,不會被決議為"SELECT EntID, 標題 INTO @tablename FROM @paramEntTableSELECTINTO表的變數名@tablename",而是"SELECTINTO表變數@tablename"。這顯然會失敗,因為你不能使用SELECT...INTO來創建和插入一個表變數;你必須DECLARE和INSERT INTO。 -
由于第1點的原因,這并不可行,而且EXEC (N'SELECT EntID, Title INTO mynewtable' @userid ' FROM ' @paramEntTable)@paramEntTable不在范圍內。變數/引數只存在于它們所定義的作用域中,它們不能從外部或內部作用域中訪問。這就是為什么EXEC ({SQL Statement})的語法是不受歡迎的,你不能對陳述句進行引數化。你應該使用sys.sp_executesql. 。
那么,解決方案是什么呢?好吧,如果你采用上面的觀點,并使用CONCAT進行連接,安全地注入你的表名,并引數化你的動態陳述句,這將作業。由于缺乏樣本資料和DDL(對于typeTableEnt),這一點沒有測驗,所以任何錯誤你都需要修復。我還假設一切都在dbo模式上,因為該模式大部分被省略了。
ALTER PROCEDURE [dbo].[Prod_EntTable] @paramEntTable dbo.typeTableEnt readonly,
@userid int
AS[/span
BEGIN
DECLARE @TableName sysname, --物件名稱的正確資料型別。
@SQL nvarchar(MAX)。
SET @TableName = CONCAT(N'mynewtable', @userid) 。
SET @SQL = N'SELECT EntID, Title INTO dbo. ' QUOTENAME(@TableName) N' FROM @paramEntTable; ';
EXEC sys.sp_executesql @SQL, N'@paramEntTable dbo.typeTableEnt READONLY', @ParamEntTable;
END。
歸
uj5u.com熱心網友回復:
我認為,你應該編輯你的代碼
。ALTER PROCEDURE [dbo].[Prod_EntTable]
@paramEntTable nvarchar(max)。
@userid int
AS
BEGIN
Declare @tablename nvarchar(20)
Set @tablename ='mynewtable' @userid
SELECT EntID, Title INTO @tablename FROM @paramEntTable
END
uj5u.com熱心網友回復:
你的sp的主要問題是,你沒有創建你想選擇的表。 所以首先你需要創建你的表,如果它不在那里。 然后你可以生成輸入陳述句。
我不確定在直接的sql查詢中的動態表名,因此我在第二個變數中生成Select INTO,然后像創建一樣執行它。
ALTER PROCEDURE [dbo].[Prod_EntTable]
@paramEntTable typeTableEnt readonly,
@userid int
AS
BEGIN
Declare @tablename nvarchar(20)
Set @tablename ='mynewtable' @userid
IF Object_ID(@tablename) IS NULL
BEGIN[/span
declare @createtablesql nvarchar(max)。
--作為一個變數,因為動態表的名字。
SET @createtablesql = 'our create statement'。
EXECUTE sp_executesql @createTableSql
END[/span
declare @selectIntoSql nvarhcar(max)。
SELECT @selectIntoSql = CONCAT('SELECT EntID, Title INTO ' ,
@tablename,' FROM ', @paramEntTable)。)
EXECUTE sp_executesql @selectIntoSql.
END
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/311055.html
標籤:
