त्वरित बैक स्टोरी, हम एक बाहरी विक्रेता के साथ काम कर रहे हैं जिसमें एक सर्वेक्षण प्रणाली है। जब आप एक नया सर्वेक्षण बनाते हैं और सिस्टम एक नई तालिका बनाता है, तो सिस्टम आवश्यक रूप से सर्वश्रेष्ठ डिज़ाइन नहीं किया जाता है:
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)
मैं एक बनाया है एसक्यूएल फिडल नमूना डेटा और कोड के साथ।
क्या इस तरह का प्रश्न लिखने का एक अलग तरीका है? क्या इसके साथ कोई ध्यान देने योग्य मुद्दे हैं?
दुर्भाग्य से, इसके साथ कई अज्ञात हैं ... हमारे पास कितने टेबल होंगे और प्रति सर्वेक्षण कितने प्रश्न होंगे। मैं कहूंगा कि हमारे पास 25-50 सर्वेक्षण होंगे, जिनमें से प्रत्येक में 2-5 प्रश्न होंगे।