180 lines
6.9 KiB
Plaintext
180 lines
6.9 KiB
Plaintext
DELIMITER //
|
|
|
|
CREATE OR REPLACE PROCEDURE `zen_create_table` (
|
|
IN p_tablename VARCHAR(100),
|
|
IN p_source_type VARCHAR(1) -- 1:zen_newtable_d 2:zen_fields join zen_function
|
|
)
|
|
/*
|
|
Function : 配合 api 可以直接產生 table 的 sp
|
|
Description: 因為只能在相同的 db 執行, 所以在 zenWinzard 或 zenBusiness 都要有此 sp 及 zen_newtable_m/zen_newtable_d
|
|
在平台的架構中雖然放在 Wizard Menu 中, 但手改 json 連到 zenBusiness(zenEIS) 等 ERP DB,
|
|
因為通常需要新增的 table 都是 MIS 要擴充功能用的
|
|
CALL zen_create_table('tmp_test01','2');
|
|
|
|
2023-07-07
|
|
因為希望參考 iCoder 的作法, 匯入 zen_fields 後, 直接就產生程式(接近一鍵產生程式碼), 所以新增 p_source_typ=2
|
|
但是 zen_fields 是 zenWinzard 的 table, 如果是分離型 db 架構, 就無法支援 p_source_typ=2 這很傷腦筋, 怎麼辦? 如果傳入 db ??
|
|
看樣子只能先獨立建立 table (p_source_typ=1), 然後匯入 zen_fields, 再產生 Code, 先這樣吧
|
|
|
|
2023-08-26 用資料庫的同義字功能, 已解決分離式資料庫的問題
|
|
|
|
Build Date : 2022/02/16
|
|
|
|
Modify History
|
|
Item Who Date Modify Docs
|
|
==== ========== ========== ================================================
|
|
1 Michael 2022/02/16 Init
|
|
2 Michael 2023/06/28 新增也可以根據 zen_function/zen_fields 來產生 Table 的寫法(必須配合 zen_function 也已經新增定義才行)
|
|
3 Michael 2023/07/29 create table 後, 要多 select 0 as code 才不會報錯
|
|
4 [改寫者] 2023-11-15 改寫為 MariaDB 版本並最佳化
|
|
*/
|
|
BEGIN
|
|
DECLARE v_sql LONGTEXT;
|
|
DECLARE v_rets LONGTEXT;
|
|
DECLARE v_maxcount INT;
|
|
DECLARE v_currid INT;
|
|
DECLARE v_nextrowid INT;
|
|
|
|
DECLARE v_fieldname VARCHAR(100);
|
|
DECLARE v_field_type VARCHAR(100);
|
|
DECLARE v_field_len SMALLINT;
|
|
DECLARE v_is_pk CHAR(1);
|
|
DECLARE v_is_auto CHAR(1);
|
|
DECLARE v_sql_tail VARCHAR(100);
|
|
DECLARE v_sql_pk VARCHAR(100);
|
|
DECLARE v_row_count INT;
|
|
|
|
-- 創建臨時表來存儲字段信息
|
|
DROP TEMPORARY TABLE IF EXISTS temp_table_fields;
|
|
CREATE TEMPORARY TABLE temp_table_fields (
|
|
fieldname VARCHAR(100),
|
|
field_type VARCHAR(100),
|
|
field_len SMALLINT,
|
|
is_pk CHAR(1),
|
|
is_auto CHAR(1),
|
|
rowid INT AUTO_INCREMENT PRIMARY KEY
|
|
);
|
|
|
|
-- 根據來源類型填充臨時表
|
|
IF IFNULL(p_source_type, '1') = '1' THEN
|
|
INSERT INTO temp_table_fields (fieldname, field_type, field_len, is_pk, is_auto)
|
|
SELECT fieldname, field_type, field_len, is_pk, is_auto
|
|
FROM zen_newtable_d
|
|
WHERE tablename = p_tablename;
|
|
ELSE
|
|
-- 使用同義字(Synonym)解決跨資料庫問題
|
|
INSERT INTO temp_table_fields (fieldname, field_type, field_len, is_pk, is_auto)
|
|
SELECT
|
|
x1.fieldname,
|
|
CASE
|
|
WHEN x1.fieldobject IN ('textarea','input-file','link-file','input-image','nvarchar') THEN 'varchar'
|
|
WHEN x1.fieldobject IN ('int','decimal','smallint') THEN x1.fieldobject
|
|
WHEN x1.fieldobject IN ('radios','progress') THEN 'smallint'
|
|
WHEN x1.fieldobject = 'input-number' THEN 'int'
|
|
WHEN x1.fieldobject IN ('input-datetime','datetime') THEN 'datetime'
|
|
WHEN x1.fieldobject = 'input-date' THEN 'date'
|
|
WHEN LOCATE('cycle', x1.fieldobject) > 0 THEN x1.fieldobject -- 獨立判斷
|
|
ELSE 'varchar'
|
|
END field_type,
|
|
x1.fieldlength AS field_len,
|
|
CASE WHEN LOCATE(x1.fieldname, x2.mainkey) > 0 THEN 'Y' ELSE 'N' END is_pk,
|
|
x2.isautoinc AS is_auto
|
|
FROM zen_fields x1
|
|
LEFT JOIN zen_function x2 ON x1.functiontag = x2.functiontag
|
|
WHERE x1.tablename = p_tablename AND x1.fieldobject <> 'formula';
|
|
END IF;
|
|
|
|
-- 初始化變量
|
|
SELECT MAX(rowid), MIN(rowid) INTO v_maxcount, v_currid FROM temp_table_fields;
|
|
|
|
SET v_rets = '';
|
|
SET v_sql_pk = '';
|
|
|
|
-- 構建字段定義
|
|
WHILE v_currid <= v_maxcount DO
|
|
-- 取得當前字段信息
|
|
SELECT fieldname, field_type, field_len, is_pk, is_auto
|
|
INTO v_fieldname, v_field_type, v_field_len, v_is_pk, v_is_auto
|
|
FROM temp_table_fields
|
|
WHERE rowid = v_currid;
|
|
|
|
SET v_sql_tail = '';
|
|
IF v_is_pk = 'Y' THEN
|
|
SET v_sql_tail = ' NOT NULL';
|
|
SET v_sql_pk = CONCAT(v_sql_pk, v_fieldname, ',');
|
|
END IF;
|
|
|
|
IF v_is_auto = 'Y' THEN
|
|
SET v_sql_tail = CONCAT(v_sql_tail, ' AUTO_INCREMENT');
|
|
END IF;
|
|
|
|
IF LOCATE('transfer', v_field_type) > 0 OR v_field_len < 0 THEN
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' ', v_field_type, '(255)', v_sql_tail, ',');
|
|
ELSEIF LOCATE('cycle', v_field_type) > 0 THEN
|
|
IF v_field_type IN ('cycle-frequency','cycle-weeks','cycle-months') THEN
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' varchar(200)', v_sql_tail, ',');
|
|
ELSE
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' datetime ', v_sql_tail, ',');
|
|
END IF;
|
|
ELSEIF LOCATE('char', v_field_type) > 0 THEN
|
|
IF v_field_len <= 0 THEN
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' ', v_field_type, '(200)', v_sql_tail, ',');
|
|
ELSE
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' ', v_field_type, '(', v_field_len, ')', v_sql_tail, ',');
|
|
END IF;
|
|
ELSE
|
|
SET v_rets = CONCAT(v_rets, ' ', v_fieldname, ' ', v_field_type, v_sql_tail, ',');
|
|
END IF;
|
|
|
|
-- 取得下一筆資料
|
|
SELECT MIN(rowid) INTO v_nextrowid FROM temp_table_fields WHERE rowid > v_currid;
|
|
SET v_currid = v_nextrowid;
|
|
END WHILE;
|
|
|
|
-- 處理主鍵定義
|
|
IF v_sql_pk = '' THEN
|
|
SET v_sql_pk = '';
|
|
SET v_rets = SUBSTRING(v_rets, 1, CHAR_LENGTH(v_rets) - 1);
|
|
ELSE
|
|
SET v_sql_pk = CONCAT(' PRIMARY KEY (', SUBSTRING(v_sql_pk, 1, CHAR_LENGTH(v_sql_pk) - 1), ')');
|
|
END IF;
|
|
|
|
-- 只有當有字段定義時才創建表
|
|
IF v_rets <> '' THEN
|
|
-- 檢查表是否存在,如果存在且無數據則刪除
|
|
SET @sql_check = CONCAT('SELECT COUNT(*) INTO @row_count FROM information_schema.tables ',
|
|
'WHERE table_schema = DATABASE() AND table_name = \'', p_tablename, '\'');
|
|
PREPARE stmt FROM @sql_check;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
IF @row_count > 0 THEN
|
|
SET @sql_check = CONCAT('SELECT COUNT(*) INTO @row_count FROM ', p_tablename);
|
|
PREPARE stmt FROM @sql_check;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
IF @row_count <= 0 THEN
|
|
SET @sql = CONCAT('DROP TABLE ', p_tablename);
|
|
PREPARE stmt FROM @sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
END IF;
|
|
END IF;
|
|
|
|
-- 創建新表
|
|
SET v_sql = CONCAT('CREATE TABLE ', p_tablename, '(',
|
|
v_rets,
|
|
v_sql_pk, ');');
|
|
|
|
-- 執行創建表的SQL
|
|
PREPARE stmt FROM v_sql;
|
|
EXECUTE stmt;
|
|
DEALLOCATE PREPARE stmt;
|
|
|
|
-- 返回成功信息
|
|
SELECT 0 AS code, 'OK' AS msg;
|
|
END IF;
|
|
END //
|
|
|
|
DELIMITER ; |