หลังจากศึกษาทฤษฎีใน เอา Matrix มาสลับ column ใน database แนวนอนแนวตั้ง และใช้ Databae: สลับตารางแนวนอนและตารางแนวตั้ง เราจะมาเริ่มทำงานจริง ๆ โดยใช้ Dynamic Stored Procedure สำหรับ SQL Server ที่สามารถคำนวณและปรับเปลี่ยนโครงสร้างการ Reshape ได้ตามชื่อตารางและชื่อคอลัมน์และจะทำการตรวจสอบ Metadata ของตารางต้นทางเองว่ามีคอลัมน์ Permission ทั้งหมดกี่คอลัมน์ แล้วทำการคลี่ (Unpivot) ข้อมูลลงตารางปลายทางโดยอัตโนมัติครับ
Dynamic Reshape Stored Procedure
CREATE PROCEDURE sp_DynamicReshapePermissions
@SourceTable NVARCHAR(128), -- ชื่อตารางต้นทาง
@TargetTable NVARCHAR(128), -- ชื่อตารางปลายทาง
@StaticCols NVARCHAR(MAX), -- คอลัมน์คงที่ (เช่น 'id, program_id')
@PermPrefix NVARCHAR(50) -- คำขึ้นต้นของคอลัมน์ที่จะ Reshape (เช่น 'Permission_')
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Cols NVARCHAR(MAX);
DECLARE @SQL NVARCHAR(MAX);
-- 1. ค้นหาคอลัมน์ที่เป็น Permissions ทั้งหมดจาก Metadata ของ Database
SELECT @Cols = COALESCE(@Cols + ', ', '') + QUOTENAME(column_name)
FROM information_schema.columns
WHERE table_name = @SourceTable
AND column_name LIKE @PermPrefix + '%'
ORDER BY ORDINAL_POSITION;
-- 2. สร้าง Dynamic SQL สำหรับการ Unpivot
-- ตรรกะนี้จะรักษาความสัมพันธ์ของ Static Columns ไว้กับทุกๆ Permission ที่แตกออกมา
SET @SQL = N'
INSERT INTO ' + QUOTENAME(@TargetTable) + ' (' + @StaticCols + ', Permission_Key, Permission_Value)
SELECT ' + @StaticCols + ', Permission_Key, Permission_Value
FROM (
SELECT ' + @StaticCols + ', ' + @Cols + '
FROM ' + QUOTENAME(@SourceTable) + '
) AS Source
UNPIVOT (
Permission_Value FOR Permission_Key IN (' + @Cols + ')
) AS Unpvt
WHERE Permission_Value IS NOT NULL;';
-- 3. Execute คำสั่ง
EXEC sp_executesql @SQL;
PRINT 'Dynamic Reshaping Completed: ' + @SourceTable + ' -> ' + @TargetTable;
END;
GO
การใช้งาน
EXEC sp_DynamicReshapePermissions
@SourceTable = 'Source_Table_Name',
@TargetTable = 'Target_Table_Name',
@StaticCols = 'id, program_id',
@PermPrefix = 'Permission_';
คำแนะนำเพิ่มเติมสำหรับ SQL Server: ก่อนรัน Store นี้ ตารางปลายทาง (TargetTable) ควรมีคอลัมน์ Permission_Key (เพื่อเก็บชื่อคอลัมน์เดิม เช่น ‘Permission_1’) และ Permission_Value เตรียมไว้รับข้อมูลด้วยครับ
อ่านเพิ่มเติม
