เลือกคอลัมน์จากชุดผลลัพธ์ของกระบวนงานที่เก็บไว้


448

ฉันมีขั้นตอนการจัดเก็บที่ส่งคืน 80 คอลัมน์และ 300 แถว ฉันต้องการเขียนตัวเลือกที่ได้รับ 2 ของคอลัมน์เหล่านั้น สิ่งที่ต้องการ

SELECT col1, col2 FROM EXEC MyStoredProc 'param1', 'param2'

เมื่อฉันใช้ไวยากรณ์ข้างต้นฉันได้รับข้อผิดพลาด:

"ชื่อคอลัมน์ไม่ถูกต้อง"

ฉันรู้ว่าวิธีที่ง่ายที่สุดคือเปลี่ยนกระบวนงานที่เก็บไว้ แต่ฉันไม่ได้เขียนและไม่สามารถเปลี่ยนแปลงได้

มีวิธีทำสิ่งที่ฉันต้องการหรือไม่?

  • ฉันสามารถสร้างตารางชั่วคราวเพื่อใส่ผลลัพธ์ แต่เนื่องจากมี 80 คอลัมน์ดังนั้นฉันจึงต้องสร้างตารางอุณหภูมิคอลัมน์ 80 เพื่อให้ได้ 2 คอลัมน์ ฉันต้องการหลีกเลี่ยงการติดตามคอลัมน์ทั้งหมดที่ส่งคืน

  • ฉันลองใช้WITH SprocResults AS ....ตามคำแนะนำของ Mark แต่มีข้อผิดพลาด 2 ข้อ

    ไวยากรณ์ไม่ถูกต้องใกล้กับคำหลัก 'EXEC'
    ไวยากรณ์ไม่ถูกต้องใกล้กับ ')'

  • ฉันพยายามประกาศตัวแปรตารางและฉันพบข้อผิดพลาดดังต่อไปนี้

    ข้อผิดพลาดการแทรก: ชื่อคอลัมน์หรือจำนวนค่าที่ให้มาไม่ตรงกับคำนิยามของตาราง

  • หากฉันลอง
    SELECT * FROM EXEC MyStoredProc 'param1', 'param2'
    ฉันพบข้อผิดพลาด:

    ไวยากรณ์ไม่ถูกต้องใกล้กับคำหลัก 'exec'


แบบสอบถามนี้ใช้งานไม่ได้เพราะ SELECT * FROM EXEC MyStoredProc 'param1', 'param2' ถ้าเป็นเช่นนั้นชื่อคอลัมน์ใดที่แสดงในชุดผลลัพธ์และคุณสามารถใช้ชื่อคอลัมน์เหล่านั้นในรายการที่คุณเลือกได้หรือไม่?
Dave Costa

5
ฉันไม่เคยพบคำตอบสำหรับสิ่งนี้
Rossini

32
คุณไม่เคยตอบคำถามสำคัญมาก! คุณกำลังถามเกี่ยวกับแพลตฟอร์ม SQL อะไร MySQL, Microsoft SQL Server, Oracle เป็นต้นดูเหมือนว่าฉันจะเป็น SQL Server แต่คุณต้องบอกคนอื่นหรือพวกเขาไม่สามารถตอบคำถามของคุณได้อย่างน่าเชื่อถือ
JMTyler

6
ก็ต้องเป็น MS-SQL EXECไม่ได้เป็นคำหลักของ MySQL (คำสั่งที่เทียบเท่าของ MySQL นั้นจัดทำขึ้น ) แม้ว่าฉันจะต้องการทราบคำตอบสำหรับ MySQL คำตอบด้านล่างเป้าหมาย T-SQL ติดแท็กใหม่
bobobobo

1
ฉันไม่เคยพบคำตอบสำหรับเรื่องนี้
Rossini

คำตอบ:


186

คุณแบ่งแบบสอบถามได้ไหม? แทรกผลลัพธ์ proc ที่เก็บไว้ลงในตัวแปรตารางหรือตารางชั่วคราว จากนั้นเลือก 2 คอลัมน์จากตัวแปรตาราง

Declare @tablevar table(col1 col1Type,..
insert into @tablevar(col1,..) exec MyStoredProc 'param1', 'param2'

SELECT col1, col2 FROM @tablevar

27
มันยังไม่ทำงานเมื่อคุณไม่ทราบคำนิยามของตาราง
Ian Boyd

ไม่รู้เกี่ยวกับประเภทนั้น พวกเขาใช้งานเช่นเดียวกับตารางชั่วคราวหรือไม่ หรือมันอยู่ในความทรงจำอย่างเคร่งครัด?
d -_- b

สิ่งนี้น่าสนใจ: sqlnerd.blogspot.com/2005/09/…
d -_- b

วิธีนี้ใช้ได้ดีถ้าจำนวนคอลัมน์ที่ระบุในตาราง temp เหมือนกับคอลัมน์ในผลลัพธ์ของกระบวนงานที่เก็บไว้ chagbert
Chagbert

83

นี่คือลิงก์ไปยังเอกสารที่ดีพอที่จะอธิบายถึงวิธีการต่าง ๆ ในการแก้ปัญหาของคุณ (แม้ว่าจะไม่สามารถใช้งานได้หลายอย่างเพราะคุณไม่สามารถแก้ไขขั้นตอนการจัดเก็บที่มีอยู่)

วิธีการแบ่งปันข้อมูลระหว่างขั้นตอนการจัดเก็บ

คำตอบของ Gulzar จะใช้งานได้ (มันเป็นเอกสารในลิงค์ด้านบน) แต่มันจะยุ่งยากในการเขียน (คุณจะต้องระบุชื่อคอลัมน์ทั้งหมด 80 คอลัมน์ในคำสั่ง @tablevar (col1, ... ) และในอนาคต หากมีการเพิ่มคอลัมน์ในสคีมาหรือมีการเปลี่ยนแปลงผลลัพธ์จะต้องมีการอัปเดตในโค้ดของคุณมิฉะนั้นจะเกิดข้อผิดพลาด


1
ฉันคิดว่าคำแนะนำของ OPENQUERY ในลิงก์นั้นใกล้เคียงกับสิ่งที่ OP ต้องการมาก
Corin

80
CREATE TABLE #Result
(
  ID int,  Name varchar(500), Revenue money
)
INSERT #Result EXEC RevenueByAdvertiser '1/1/10', '2/1/10'
SELECT * FROM #Result ORDER BY Name
DROP TABLE #Result

ที่มา:
http://stevesmithblog.com/blog/select-from-a-stored-procedure/


@LawfulHacker ศักดิ์สิทธิ์สูบบุหรี่ คุณกำลังทำอะไรใน SQL Server 2000 ในปี 2014
John Zabroski

1
บริษัท ขนาดใหญ่ที่มีระบบเดิม: D
LawfulHacker

39

สิ่งนี้ใช้งานได้สำหรับฉัน: (เช่นฉันต้องการเพียง 2 คอลัมน์จาก 30+ คืนโดยsp_help_job)

SELECT name, current_execution_status 
FROM OPENQUERY (MYSERVER, 
  'EXEC msdb.dbo.sp_help_job @job_name = ''My Job'', @job_aspect = ''JOB''');  

ก่อนหน้านี้จะใช้ได้ฉันต้องเปิดใช้งานสิ่งนี้:

sp_serveroption 'MYSERVER', 'DATA ACCESS', TRUE;

.... เพื่ออัพเดทsys.serversตาราง (เช่นการใช้การอ้างอิงตนเองภายใน OPENQUERY ดูเหมือนว่าจะถูกปิดใช้งานตามค่าเริ่มต้น)

สำหรับความต้องการที่เรียบง่ายของฉันฉันพบว่าไม่มีปัญหาที่อธิบายไว้ในส่วนของOPENQUERYของลิงค์ยอดเยี่ยมของ Lance

Rossini หากคุณต้องการตั้งค่าพารามิเตอร์อินพุตแบบไดนามิกการใช้ OPENQUERY จะทำให้ยุ่งมากขึ้น:

DECLARE @innerSql varchar(1000);
DECLARE @outerSql varchar(1000);

-- Set up the original stored proc definition.
SET @innerSql = 
'EXEC msdb.dbo.sp_help_job @job_name = '''+@param1+''', @job_aspect = N'''+@param2+'''' ;

-- Handle quotes.
SET @innerSql = REPLACE(@innerSql, '''', '''''');

-- Set up the OPENQUERY definition.
SET @outerSql = 
'SELECT name, current_execution_status 
FROM OPENQUERY (MYSERVER, ''' + @innerSql + ''');';

-- Execute.
EXEC (@outerSql);

ฉันไม่แน่ใจเกี่ยวกับความแตกต่าง (ถ้ามี) ระหว่างการใช้sp_serveroptionเพื่ออัปเดตการsys.serversอ้างอิงตนเองที่มีอยู่โดยตรงกับการใช้sp_addlinkedserver(ตามที่อธิบายไว้ในลิงก์ของแลนซ์) เพื่อสร้างสำเนา / นามแฝง

หมายเหตุ 1: ฉันชอบ OPENQUERY มากกว่า OPENROWSET เนื่องจาก OPENQUERY ไม่ต้องการคำนิยามสตริงการเชื่อมต่อภายใน proc

หมายเหตุ 2: ต้องบอกว่าทั้งหมดนี้: โดยปกติแล้วฉันจะใช้ INSERT ... EXEC :) โดยปกติฉันใช้เวลาพิมพ์เพิ่มอีก 10 นาที แต่ถ้าฉันสามารถช่วยได้ฉันไม่ชอบที่จะ
ใช้คำพูดคำกริยา: (a) ภายในเครื่องหมายคำพูดภายใน คำพูดและ
(b) ตาราง sys และ / หรือการตั้งค่าการอ้างอิงตนเองที่เชื่อมโยงกับเซิร์ฟเวอร์ (เช่นสำหรับสิ่งเหล่านี้ฉันต้องขอร้องกรณีของฉันกับ DBA ที่ทรงพลังทั้งหมดของเรา :)

อย่างไรก็ตามในกรณีนี้ฉันไม่สามารถใช้ INSERT ... EXEC build ตามที่sp_help_jobใช้แล้ว ("คำสั่ง INSERT EXEC ไม่สามารถซ้อนกันได้")


3
ฉันเคยมี 13 คำพูดติดต่อกันในแบบไดนามิก sql-that-
created

ฉันต้องตรวจสอบว่างานเสร็จหรือไม่ "คำสั่ง INSERT EXEC ไม่สามารถซ้อนกันได้" ฉันเกลียดคุณ Microsoft
alexkovelsky

11

เพื่อให้บรรลุเป้าหมายนี้อันดับแรกคุณต้องสร้างสิ่ง#test_tableต่อไปนี้:

create table #test_table(
    col1 int,
    col2 int,
   .
   .
   .
    col80 int
)

ตอนนี้รันโพรซีเดอร์และใส่ค่าใน#test_table:

insert into #test_table
EXEC MyStoredProc 'param1', 'param2'

ตอนนี้คุณดึงค่าจาก#test_table:

select col1,col2....,col80 from #test_table

2
มีประโยชน์ในการสร้างตาราง temp แทนตัวแปร table หรือไม่?
Dave Kelly

1
ทางออกที่ดีที่สุดที่ฉันพบใน stackoverflow! :)
Umar

4
ต้องทำอย่างไรหากฉันต้องการคอลัมน์เดียวจากกระบวนงานที่เก็บอื่น
Keval Patel

11

หากคุณสามารถแก้ไขขั้นตอนการจัดเก็บของคุณคุณสามารถใส่คำจำกัดความของคอลัมน์ที่ต้องการเป็นพารามิเตอร์และใช้ตารางชั่วคราวที่สร้างขึ้นอัตโนมัติ:

CREATE PROCEDURE sp_GetDiffDataExample
      @columnsStatement NVARCHAR(MAX) -- required columns statement (e.g. "field1, field2")
AS
BEGIN
    DECLARE @query NVARCHAR(MAX)
    SET @query = N'SELECT ' + @columnsStatement + N' INTO ##TempTable FROM dbo.TestTable'
    EXEC sp_executeSql @query
    SELECT * FROM ##TempTable
    DROP TABLE ##TempTable
END

ในกรณีนี้คุณไม่จำเป็นต้องสร้างตารางชั่วคราวด้วยตนเอง - มันจะถูกสร้างขึ้นโดยอัตโนมัติ หวังว่านี่จะช่วยได้


โปรดใช้ความระมัดระวัง ## ตารางเนื่องจากมีการแชร์ระหว่างเซสชัน
eKelvin

1
คุณสามารถค้นหาคำอธิบายสั้น ๆ เกี่ยวกับความแตกต่างระหว่างตาราง # และ ## ได้ที่stackoverflow.com/a/34081438/352820
eKelvin

มีแนวโน้มที่จะฉีด SQL หรือไม่
Bushrod

11

การรู้ว่าทำไมจึงเป็นเรื่องยาก กระบวนงานที่เก็บไว้อาจส่งคืนข้อความเท่านั้น (พิมพ์ 'ข้อความ') หรืออาจส่งคืนหลายตารางหรืออาจไม่มีตารางกลับเลย

ดังนั้นสิ่งที่ชอบSELECT * FROM (exec sp_tables) Table1 จะไม่ทำงาน


12
SQL Server สามารถเพิ่มข้อผิดพลาดได้หากเกิดขึ้น เช่นถ้าฉันเขียนแบบสอบถามย่อยที่ส่งกลับมากกว่าหนึ่งค่า ใช่มันสามารถเกิดขึ้นได้ แต่ในความเป็นจริงมันไม่ได้ และถึงแม้ว่าจะเป็นเช่นนั้นก็ไม่ใช่เรื่องยากที่จะแจ้งข้อผิดพลาด
Ian Boyd

8

(สมมติว่าเซิร์ฟเวอร์ SQL)

วิธีเดียวที่จะทำงานกับผลลัพธ์ของกระบวนงานที่เก็บไว้ใน T-SQL คือการใช้INSERT INTO ... EXECไวยากรณ์ ที่ให้ตัวเลือกในการแทรกลงในตารางชั่วคราวหรือตัวแปรตารางและจากนั้นเลือกข้อมูลที่คุณต้องการ


1
ที่ต้องรู้นิยามของตาราง ไม่มีประโยชน์.
Triynko

8

แฮ็คด่วนจะเป็นการเพิ่มพารามิเตอร์ใหม่'@Column_Name'และมีฟังก์ชั่นการโทรกำหนดชื่อคอลัมน์ที่จะดึง ในส่วนส่งคืนของ sproc ของคุณคุณจะมี if / else งบและส่งกลับเฉพาะคอลัมน์ที่ระบุหรือถ้าว่างเปล่า - ส่งคืนทั้งหมด

CREATE PROCEDURE [dbo].[MySproc]
        @Column_Name AS VARCHAR(50)
AS
BEGIN
    IF (@Column_Name = 'ColumnName1')
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1'
        END
    ELSE
        BEGIN
            SELECT @ColumnItem1 as 'ColumnName1', @ColumnItem2 as 'ColumnName2', @ColumnItem3 as 'ColumnName3'
        END
END

7

หากคุณกำลังทำสิ่งนี้เพื่อตรวจสอบความถูกต้องของข้อมูลด้วยตนเองคุณสามารถทำได้ด้วย LINQPad

สร้างการเชื่อมต่อกับฐานข้อมูลใน LinqPad จากนั้นสร้างคำสั่ง C # คล้ายกับที่แสดงต่อไปนี้:

DataTable table = MyStoredProc (param1, param2).Tables[0];
(from row in table.AsEnumerable()
 select new
 {
  Col1 = row.Field<string>("col1"),
  Col2 = row.Field<string>("col2"),
 }).Dump();

อ้างอิงhttp://www.global-webnet.net/blogengine/post/2008/09/10/LINQPAD-Using-Stored-Procedures-Accessing-a-DataSet.aspx


7

สำหรับ SQL Server ฉันพบว่ามันใช้งานได้ดี:

สร้างตารางชั่วคราว (หรือตารางถาวรไม่สำคัญ) และทำการแทรกคำสั่งกับโพรซีเดอร์ที่เก็บ ชุดผลลัพธ์ของ SP ควรตรงกับคอลัมน์ในตารางของคุณมิฉะนั้นคุณจะได้รับข้อผิดพลาด

นี่คือตัวอย่าง:

DECLARE @temp TABLE (firstname NVARCHAR(30), lastname nvarchar(50));

INSERT INTO @temp EXEC dbo.GetPersonName @param1,@param2;
-- assumption is that dbo.GetPersonName returns a table with firstname / lastname columns

SELECT * FROM @temp;

แค่นั้นแหละ!


สำหรับสิ่งนี้จำเป็นต้องสร้างสำเนาของคำนิยามตาราง มีวิธีหลีกเลี่ยงหรือไม่
Hardik

7

ตามที่ถูกกล่าวถึงในคำถามมันยากที่จะกำหนดตารางอุณหภูมิคอลัมน์ 80 ก่อนที่จะดำเนินการขั้นตอนการจัดเก็บ

วิธีอื่นในการนี้คือการเติมตารางตามชุดผลลัพธ์ของโพรซีเดอร์ที่เก็บ

SELECT * INTO #temp FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;'
                                   ,'EXEC MyStoredProc')

หากคุณได้รับข้อผิดพลาดใด ๆ คุณต้องเปิดใช้งานคิวรีแบบกระจายเฉพาะกิจโดยดำเนินการแบบสอบถามต่อไปนี้

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

ในการดำเนินการsp_configureกับพารามิเตอร์ทั้งสองเพื่อเปลี่ยนตัวเลือกการกำหนดค่าหรือเพื่อเรียกใช้RECONFIGUREคำสั่งคุณต้องได้รับALTER SETTINGSสิทธิ์ระดับเซิร์ฟเวอร์

ตอนนี้คุณสามารถเลือกคอลัมน์เฉพาะของคุณจากตารางที่สร้างขึ้น

SELECT col1, col2
FROM #temp

4

ลองนี้

use mydatabase
create procedure sp_onetwothree as
select 1 as '1', 2 as '2', 3 as '3'
go
SELECT a.[1], a.[2]
FROM OPENROWSET('SQLOLEDB','myserver';'sa';'mysapass',
    'exec mydatabase.dbo.sp_onetwothree') AS a
GO

1
ฮ่า ๆ - เขาไม่ได้ เขาเข้ารหัสมันลงในการภาวนาของขั้นตอนการจัดเก็บแทนซึ่งสามารถรับได้ง่ายกว่าโดยไม่ต้องเข้าถึงฐานข้อมูลโดยการดมกลิ่นเครือข่าย
Martin Milan

ค่อนข้างง่ายที่จะเอามันออกจาก Github ด้วย
nomen

3

ฉันรู้ว่าการดำเนินการจาก sp และแทรกลงในตาราง temp หรือตัวแปรตารางจะเป็นตัวเลือก แต่ฉันไม่คิดว่าเป็นความต้องการของคุณ ตามความต้องการของคุณข้อความค้นหาด้านล่างนี้ควรใช้งานได้:

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);uid=test;pwd=test'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

หากคุณมีการเชื่อมต่อที่เชื่อถือได้ให้ใช้ข้อความค้นหาด้านล่างนี้:

Declare @sql nvarchar(max)
Set @sql='SELECT   col1, col2 FROM OPENROWSET(''SQLNCLI'', ''Server=(local);Trusted_Connection=yes;'',
     ''EXEC MyStoredProc ''''param1'''', ''''param2'''''')'
 Exec(@sql)

หากคุณได้รับข้อผิดพลาดในการเรียกใช้คำสั่งด้านบนให้เรียกใช้คำสั่งด้านล่างนี้:

sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO

ฉันหวังว่าสิ่งนี้จะช่วยให้คนที่ต้องเผชิญกับปัญหาทำนองนี้ หากใครบางคนลองกับตัวแปร temp table หรือ table ที่ควรจะเป็นแบบนี้ แต่ในสถานการณ์นี้คุณควรรู้จำนวน sp ที่คุณส่งคืนแล้วคุณควรสร้างคอลัมน์จำนวนมากในตัวแปร temp table หรือ table table:

--for table variable 
Declare @t table(col1 col1Type, col2 col2Type)
insert into @t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM @t

--for temp table
create table #t(col1 col1Type, col2 col2Type)
insert into #t exec MyStoredProc 'param1', 'param2'
SELECT col1, col2 FROM #t

1

สำหรับทุกคนที่มี SQL 2012 หรือใหม่กว่าฉันสามารถทำสิ่งนี้ได้ด้วยโพรซีเดอร์ที่เก็บไว้ซึ่งไม่เป็นแบบไดนามิกและมีคอลัมน์เดียวกันเอาท์พุททุกครั้ง

แนวคิดทั่วไปคือฉันสร้างคิวรีแบบไดนามิกเพื่อสร้างแทรกเลือกจากและวางตาราง temp และดำเนินการหลังจากสร้างเสร็จแล้ว ฉันสร้างตารางชั่วคราวแบบไดนามิกโดยเรียกชื่อคอลัมน์และประเภทจากขั้นตอนการจัดเก็บครั้งแรก

หมายเหตุ: มีดีกว่าการแก้ปัญหาสากลมากขึ้นที่จะทำงานกับสายน้อยลงรหัสถ้าคุณยินดี / ความสามารถในการปรับปรุงการกำหนดค่า SP OPENROWSETหรือการเปลี่ยนแปลงและการใช้งาน ใช้ด้านล่างหากคุณไม่มีวิธีอื่น

DECLARE @spName VARCHAR(MAX) = 'MyStoredProc'
DECLARE @tempTableName VARCHAR(MAX) = '#tempTable'

-- might need to update this if your param value is a string and you need to escape quotes
DECLARE @insertCommand VARCHAR(MAX) = 'INSERT INTO ' + @tempTableName + ' EXEC MyStoredProc @param=value'

DECLARE @createTableCommand VARCHAR(MAX)

-- update this to select the columns you want
DECLARE @selectCommand VARCHAR(MAX) = 'SELECT col1, col2 FROM ' + @tempTableName

DECLARE @dropCommand VARCHAR(MAX) = 'DROP TABLE ' + @tempTableName

-- Generate command to create temp table
SELECT @createTableCommand = 'CREATE TABLE ' + @tempTableName + ' (' +
    STUFF
    (
        (
            SELECT ', ' + CONCAT('[', name, ']', ' ', system_type_name)
            FROM sys.dm_exec_describe_first_result_set_for_object
            (
              OBJECT_ID(@spName), 
              NULL
            )
            FOR XML PATH('')
        )
        ,1
        ,1
        ,''
    ) + ')'

EXEC( @createTableCommand + ' '+ @insertCommand + ' ' + @selectCommand + ' ' + @dropCommand)

0

วิธีที่ง่ายที่สุดที่จะทำถ้าคุณต้องการเพียงแค่ครั้งเดียว:

ส่งออกไปยัง excel ในตัวช่วยสร้างการนำเข้าและส่งออกแล้วนำเข้า excel นี้ลงในตาราง


4
จุดทั้งหมดของการสร้าง proc ที่เก็บไว้นั้นสามารถนำมาใช้ซ้ำได้ คำตอบของคุณขัดแย้งกับสิ่งนั้นโดยสิ้นเชิง
deutschZuid

6
เพื่อตอบโต้ deutschZuid ในโพสต์ต้นฉบับเขาไม่ได้พูดถึงว่าเขาต้องการนำสิ่งนี้กลับมาใช้ใหม่หรือไม่หรือถ้าเขาเพียงแค่พยายามดูผลลัพธ์ของ proc ที่เก็บไว้ มาร์ตินพูดถูกวิธีนี้อาจเป็นวิธีที่ง่ายที่สุดถ้าเขาต้องการทำเพียงครั้งเดียว
บิชอป

0

สร้างมุมมองแบบไดนามิกและรับผลจากมัน .......

CREATE PROCEDURE dbo.usp_userwise_columns_value
(
    @userid BIGINT
)
AS 
BEGIN
        DECLARE @maincmd NVARCHAR(max);
        DECLARE @columnlist NVARCHAR(max);
        DECLARE @columnname VARCHAR(150);
        DECLARE @nickname VARCHAR(50);

        SET @maincmd = '';
        SET @columnname = '';
        SET @columnlist = '';
        SET @nickname = '';

        DECLARE CUR_COLUMNLIST CURSOR FAST_FORWARD
        FOR
            SELECT columnname , nickname
            FROM dbo.v_userwise_columns 
            WHERE userid = @userid

        OPEN CUR_COLUMNLIST
        IF @@ERROR <> 0
            BEGIN
                ROLLBACK
                RETURN
            END   

        FETCH NEXT FROM CUR_COLUMNLIST
        INTO @columnname, @nickname

        WHILE @@FETCH_STATUS = 0
            BEGIN
                SET @columnlist = @columnlist + @columnname + ','

                FETCH NEXT FROM CUR_COLUMNLIST
                INTO @columnname, @nickname
            END
        CLOSE CUR_COLUMNLIST
        DEALLOCATE CUR_COLUMNLIST  

        IF NOT EXISTS (SELECT * FROM sys.views WHERE name = 'v_userwise_columns_value')
            BEGIN
                SET @maincmd = 'CREATE VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END
        ELSE
            BEGIN
                SET @maincmd = 'ALTER VIEW dbo.v_userwise_columns_value AS SELECT sjoid, CONVERT(BIGINT, ' + CONVERT(VARCHAR(10), @userid) + ') as userid , ' 
                            + CHAR(39) + @nickname + CHAR(39) + ' as nickname, ' 
                            + @columnlist + ' compcode FROM dbo.SJOTran '
            END

        --PRINT @maincmd
        EXECUTE sp_executesql @maincmd
END

-----------------------------------------------
SELECT * FROM dbo.v_userwise_columns_value

-1

ฉันจะตัดและวาง SP ดั้งเดิมและลบคอลัมน์ทั้งหมดยกเว้น 2 ที่คุณต้องการ หรือ. ฉันจะนำชุดผลลัพธ์กลับมาจับคู่กับวัตถุทางธุรกิจที่เหมาะสมจากนั้น LINQ จะแสดงสองคอลัมน์


1
คนไม่ทำสิ่งนี้ สิ่งนี้จะเป็นการละเมิดหลักการของ DRY เมื่อสิ่งต่าง ๆ เปลี่ยนแปลงไม่ได้ตอนนี้คุณจะต้องติดตามและป้อนข้อมูลการเปลี่ยนแปลงของคุณในทุกสถานที่
jriver27
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.