first commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
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 ;
|
||||
Reference in New Issue
Block a user