2009-03-19 20 views
38

Mã này là như sau:động SQL kết quả vào bảng temp trong SQL Stored thủ tục

ALTER PROCEDURE dbo.pdpd_DynamicCall 
@SQLString varchar(4096) = null 

AS 

Begin 

    create TABLE #T1 (column_1 varchar(10) , column_2 varchar(100)) 

    insert into #T1 
     execute ('execute ' + @SQLString) 

    select * from #T1 

End 

Vấn đề là tôi muốn gọi thủ tục khác nhau có thể trả lại các cột khác nhau. Vì vậy, tôi sẽ phải xác định bảng # T1 chung. Nhưng tôi không biết làm thế nào.

Có ai có thể giúp tôi về vấn đề này không?

+1

Sound như bạn nên ngừng cố gắng sử dụng thủ tục lưu trữ và sử dụng đồng bằng cũ script parametered sql. –

Trả lời

34

Hãy thử:

SELECT into #T1 execute ('execute ' + @SQLString) 

Và đây mùi hôi thật giống như một lỗ hổng SQL injection.


chỉnh (mỗi bình luận @ Carpediem của):

INSERT into #T1 execute ('execute ' + @SQLString) 

cũng có, bỏ qua 'execute' nếu chuỗi sql là một cái gì đó khác hơn là một thủ tục

+0

Khó khăn chấp nhận câu trả lời, tôi không thể thực hiện công việc này! Đầu tiên nó phàn nàn rằng không có * sau khi SELECT. Và khi tôi đặt nó, nó phàn nàn rằng không có bảng để lựa chọn .. SELECT * INTO #tmp_input EXECUTE ('SELECT 1 AS test'); >>> Lỗi cơ sở dữ liệu máy chủ SQL: Phải chỉ định bảng để chọn. Trên SQL Server 2005! – ercan

+3

Tôi nghĩ câu trả lời là * INSERT * thành # T1 thực thi ('execute' + @SQLString) ... –

+3

Nó không hoạt động ... – sreejithsdev

0

Không chắc chắn nếu tôi hiểu rõ, nhưng có lẽ bạn có thể tạo câu lệnh CREATE bên trong một chuỗi, sau đó thực hiện chuỗi đó? Bằng cách đó bạn có thể thêm bao nhiêu cột tùy thích.

+0

nhưng, tôi không biết các cột, nó là động. – Dhana

31

Bạn có thể định nghĩa một bảng động chỉ khi bạn đang chèn vào nó một cách năng động, nhưng vấn đề là với phạm vi của các bảng tạm thời. Ví dụ: mã này:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE #T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO #T1 (Col1) VALUES ('This will not work.') 
SELECT * FROM #T1 

sẽ trả về với lỗi "Tên đối tượng không hợp lệ '# T1'". Điều này là do bảng tạm thời # T1 được tạo ở mức "thấp hơn" so với khối thực thi mã. Để khắc phục, sử dụng một bảng tạm thời toàn cầu:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE ##T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO ##T1 (Col1) VALUES ('This will work.') 
SELECT * FROM ##T1 

Hope this helps, Jesse

+0

thực sự, nó đã giúp. cảm ơn bạn! – user219628

+2

Đây là nó! Bây giờ tôi có thể tạo bảng bên trong thủ tục được lưu trữ của tôi, với tên được truyền qua một đối số! Nếu tôi có thể cho 10 phiếu bầu! –

14

Hãy cẩn thận của một giải pháp bảng temp toàn cầu vì điều này có thể thất bại nếu hai người dùng sử dụng thường xuyên cùng đồng thời gian như một bảng tạm thời toàn cầu có thể được nhìn thấy bởi tất cả người dùng ...

7
INSERT INTO #TempTable 
EXEC(@SelectStatement) 
0
DECLARE @EmpGroup INT =3 , 
     @IsActive BIT=1 

DECLARE @tblEmpMaster AS TABLE 
     (EmpCode VARCHAR(20),EmpName VARCHAR(50),EmpAddress VARCHAR(500)) 

INSERT INTO @tblEmpMaster EXECUTE SPGetEmpList @EmpGroup,@IsActive 

SELECT * FROM @tblEmpMaster 
8

tạo một bảng tạm thời toàn cầu với một GUID trong tên tự động. Sau đó, bạn có thể làm việc với nó trong mã của bạn, thông qua dyn sql, mà không lo lắng rằng một quá trình khác gọi là sproc tương tự sẽ sử dụng nó. Điều này rất hữu ích khi bạn không biết những gì mong đợi từ bảng được chọn bên dưới mỗi khi nó chạy, do đó bạn không thể tạo bảng tạm thời một cách rõ ràng trước. ví dụ: - bạn cần phải sử dụng SELECT * VÀO cú pháp

DECLARE @TmpGlobalTable varchar(255) = 'SomeText_' + convert(varchar(36),NEWID()) 

-- select @TmpGlobalTable 

-- build query 
    SET @Sql = 
     'SELECT * INTO [##' + @TmpGlobalTable + '] FROM SomeTable' 
EXEC (@Sql) 
EXEC ('SELECT * FROM [##' + @TmpGlobalTable + '] ') 
EXEC ('DROP TABLE [##' + @TmpGlobalTable + ']') 
PRINT 'Dropped Table ' + @TmpGlobalTable 
+0

Nếu bạn có tên cột động, đây là cách để đi. – jbd

+0

Giải pháp tốt. Lưu ý các dấu ngoặc vuông quanh tên bảng: NEWID được chuyển đổi thành varchar chứa "-" không hợp lệ trong tên đối tượng nếu không. – SebTHU

0
CREATE PROCEDURE dbo.pdpd_DynamicCall 
AS 
DECLARE @SQLString_2 NVARCHAR(4000) 
SET NOCOUNT ON 
Begin 
    --- Create global temp table 
    CREATE TABLE ##T1 (column_1 varchar(10) , column_2 varchar(100)) 

    SELECT @SQLString_2 = 'INSERT INTO ##T1(column_1, column_2) SELECT column_1 = "123", column_2 = "MUHAMMAD IMRON"' 
    SELECT @SQLString_2 = REPLACE(@SQLString_2, '"', '''') 

    EXEC SP_EXECUTESQL @SQLString_2 

    --- Test Display records 
    SELECT * FROM ##T1 

    --- Drop global temp table 
    IF OBJECT_ID('tempdb..##T1','u') IS NOT NULL 
    DROP TABLE ##T1 
End 
Các vấn đề liên quan