গতিশীলভাবে তৈরি টেবিলের ডেটা ফিরিয়ে আনার জন্য সঞ্চিত পদ্ধতি ced


10

দ্রুত ফিরে আসার গল্প, আমরা বাইরের একজন বিক্রেতার সাথে কাজ করছি যার একটি জরিপ ব্যবস্থা রয়েছে। আপনি যখন নতুন জরিপ তৈরি করেন এবং সিস্টেমটি একটি নতুন টেবিল তৈরি করে, তখন অবশ্যই সিস্টেমটি সর্বোত্তমভাবে নকশাকৃত হয় না:

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 এ শুরু করে না। প্রশ্ন কলামগুলি তাদের সারণিতে নির্ধারিত আইডির উপর ভিত্তি করে তৈরি করা হবে।

অন্য কোন সিস্টেমে প্রেরণের জন্য আমাদের জরিপ টেবিলগুলির সমস্ত থেকে ডেটা উত্তোলনের প্রয়োজন নেই এবং এদিকেই সমস্যাটি আসে query শেষ অ্যাপ্লিকেশন, অন্যান্য সিস্টেম এই ধরণের কাঠামো পরিচালনা করতে পারে না। তাদের উপভোগ করার জন্য তাদের ডেটা সামঞ্জস্য রাখতে হবে।

সুতরাং আমাকে একটি সঞ্চিত প্রক্রিয়া লেখার দায়িত্ব দেওয়া হয়েছিল যা সমস্ত জরিপ সারণী থেকে ডেটা বের করে নীচের বিন্যাসে রাখবে:

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 টি প্রশ্ন থাকবে।


1
আমি জিজ্ঞাসা করতে ভয় পাই, কিন্তু, "কত টেবিল?"
আরবেরি ইয়ং

টুইট করুন এটি সমস্যার একটি অংশ।
তারিন

আমাদের তারপর একটি পরিসীমা দিন। এটি একটি দুর্দান্ত ব্যাপার।
আরবেরি ইয়ং

আমি 25-50 টেবিল থেকে যে কোনও জায়গায় বলব।
ট্যারিন

উত্তর:


2

চ্যাটের লোকদের মন্তব্যের ভিত্তিতে, আমি সিদ্ধান্ত নিয়েছিলাম INSERT INTOযে শেষের দিকে চালিত করার জন্য একটি দীর্ঘ এসকিউএল বিবৃতি তৈরির পরিবর্তে আমার স্ক্রিপ্টটি সামান্য টেম্পলে পরিবর্তন করা হবে । সুতরাং শেষ পর্যন্ত আমার সঞ্চিত পদ্ধতিতে নিম্নলিখিতটি রয়েছে:

create table #SurveyData
(
    tableName varchar(50),
    columnName varchar(50),
    columnId int,
    rownum int
)

create table #results
(
    SurveyId int,
    InstanceId int,
    QuestionNumber int,
    Response varchar(1000)
)

-- insert the survey table structures for use
insert into #SurveyData (tableName, columnName, columnId, rownum)
select tables1.name, cols1.name, column_id, ROW_NUMBER() over(order by tables1.name, column_id)
from sys.all_columns cols1
inner join 
(
    SELECT *
    FROM sys.all_objects
    WHERE type = 'U' 
    AND upper(name) like 'LIBRARY%' 
) Tables1
    ON cols1.object_id = tables1.object_id
WHERE cols1.name Like 'Q_%'
ORDER BY tables1.name, column_id;


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 = 'INSERT INTO #results ' +
                    ' 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 + ''''

        exec(@sql)

        SET @RowCount = @RowCount + 1       
    END

    SELECT SurveyId, InstanceId, QuestionNumber, Response
    FROM #results

drop table #SurveyData
drop table #results

চূড়ান্ত স্ক্রিপ্ট সহ এসকিউএল ফিডল দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.