เรื่องราวย้อนกลับอย่างรวดเร็วเรากำลังทำงานกับผู้ขายภายนอกที่มีระบบสำรวจ ระบบไม่ได้ถูกออกแบบมาอย่างดีที่สุดเมื่อคุณสร้างแบบสำรวจใหม่และระบบจะสร้างตารางใหม่เช่น:
Tables
____
Library_1 -- table for Survey 1
SurveyId int
InstanceId int
Q_1 varchar(50)
Library_2 -- table for Survey 2
SurveyId int
InstanceId int
Q_2 int
Q_3 int
Q_4 varchar(255)
ตารางจะถูกสร้างขึ้นด้วยการSurveyId
ที่ส่วนท้ายของชื่อ ( Library_
) และคอลัมน์คำถามจะถูกสร้างขึ้นด้วยการQuestionId
ที่ส่วนท้ายของมัน ( Q_
) ในการชี้แจงคำถามจะถูกเก็บไว้ในตารางแยกต่างหากดังนั้นในขณะที่รหัสคำถามนั้นเรียงตามลำดับโดยไม่เริ่มต้นที่ 1 สำหรับแต่ละแบบสำรวจ คอลัมน์คำถามจะขึ้นอยู่กับรหัสที่กำหนดให้กับพวกเขาในตาราง
ดูเหมือนง่ายพอที่จะสืบค้นยกเว้นเราจำเป็นต้องดึงข้อมูลจากตารางสำรวจทั้งหมดที่จะส่งไปยังระบบอื่นและนี่คือที่มาของปัญหาเนื่องจากตารางจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อมีการเพิ่มแบบสำรวจใหม่โดยหน้า แอปพลิเคชันสิ้นสุดระบบอื่นไม่สามารถจัดการกับโครงสร้างประเภทนี้ได้ พวกเขาต้องการข้อมูลที่สอดคล้องกันเพื่อให้สามารถบริโภคได้
ดังนั้นฉันจึงมอบหมายให้เขียนโพรซีเดอร์ที่เก็บไว้ซึ่งจะดึงข้อมูลจากตารางสำรวจทั้งหมดและวางไว้ในรูปแบบต่อไปนี้:
SurveyId InstanceId QNumber Response
________ __________ _______ ________
1 1 1 great
1 2 1 the best
2 9 2 10
3 50 50 test
โดยการมีข้อมูลสำหรับตารางทั้งหมดในรูปแบบเดียวกันดังนั้นใคร ๆ ก็สามารถบริโภคได้ไม่ว่าจะมีตารางและคำถามสำรวจจำนวนเท่าใด
ฉันเขียนขั้นตอนการจัดเก็บที่ดูเหมือนว่าจะใช้งานได้ แต่ฉันสงสัยว่าฉันทำอะไรหายไปหรือมีวิธีที่ดีกว่าในการจัดการกับสถานการณ์ประเภทนี้
รหัสของฉัน:
declare @sql varchar(max) = ''
declare @RowCount int = 1
declare @TotalRecords int = (SELECT COUNT(*) FROM SurveyData)
Declare @TableName varchar(50) = ''
Declare @ColumnName varchar(50) = ''
WHILE @RowCount <= @TotalRecords
BEGIN
SELECT @TableName = tableName, @ColumnName = columnName
FROM SurveyData
WHERE @RowCount = rownum
SET @sql = @sql +
' SELECT s.SurveyId
, s.InstanceId
, CASE WHEN columnName = ''' + @ColumnName + ''' THEN REPLACE(columnName, ''Q_'', '''') ELSE '''' END as QuestionNumber
, Cast(s.' + @ColumnName + ' as varchar(1000)) as ''Response''
FROM SurveyData t
INNER JOIN ' + @TableName + ' s' +
' ON REPLACE(t.tableName, ''Library_'', '''') = s.SurveyID ' +
' WHERE t.columnName = ''' + @ColumnName + ''''
IF @RowCount != @TotalRecords
BEGIN
set @sql = @sql + ' UNION ALL'
END
SET @RowCount = @RowCount + 1
END
exec(@sql)
ฉันสร้างSQL Fiddleพร้อมข้อมูลตัวอย่างและรหัสแล้ว
มีวิธีอื่นในการเขียนแบบสอบถามประเภทนี้หรือไม่? มีปัญหาที่เห็นได้ชัดเจนหรือไม่?
น่าเสียดายที่มีสิ่งที่ไม่ทราบจำนวนมากในเรื่องนี้ ... เราจะมีกี่ตารางและกี่คำถามต่อแบบสำรวจ ฉันจะบอกว่าเราจะมีการสำรวจระหว่าง 25-50 ครั้งโดยมีคำถาม 2-5 ข้อแต่ละข้อ