convert to gitea

This commit is contained in:
2025-09-15 13:33:34 +09:00
commit 95882ac072
277 changed files with 46023 additions and 0 deletions

View File

@ -0,0 +1,59 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_add_category`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_category_name VARCHAR(40),
OUT p_new_category_id TINYINT UNSIGNED,
OUT p_result_message VARCHAR(255)
)
COMMENT '카테고리 추가 및 로그 기록 (ID 자동 할당)'
BEGIN
DECLARE v_existing_cat_id TINYINT UNSIGNED DEFAULT NULL;
DECLARE v_next_id TINYINT UNSIGNED;
DECLARE v_max_id TINYINT UNSIGNED;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_new_category_id = NULL; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_new_category_id = NULL; SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSEIF p_category_name IS NULL OR p_category_name = '' THEN
SET p_new_category_id = NULL; SET p_result_message = '카테고리 이름은 필수입니다.';
ELSE
-- 카테고리 이름 중복 검사
SELECT category_id INTO v_existing_cat_id FROM resource_category WHERE LOWER(category_name) = LOWER(p_category_name) LIMIT 1;
IF v_existing_cat_id IS NOT NULL THEN
SET p_new_category_id = NULL; SET p_result_message = CONCAT('이미 사용 중인 카테고리 이름입니다: ', p_category_name);
ELSE
-- 다음 ID 할당
SELECT IFNULL(MAX(category_id), 0) INTO v_max_id FROM resource_category;
SET v_next_id = v_max_id + 1;
IF v_next_id > 255 THEN
SET p_new_category_id = NULL; SET p_result_message = '더 이상 카테고리 ID를 할당할 수 없습니다 (최대 255).';
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO resource_category (category_id, category_name) VALUES (v_next_id, p_category_name);
SET p_new_category_id = v_next_id;
INSERT INTO log_add_category (log_date, admin_user_id, actor_description, category_id, category_name)
VALUES (v_now, p_admin_user_id, p_actor_description, p_new_category_id, p_category_name);
COMMIT;
SET p_result_message = CONCAT('카테고리 "', p_category_name, '" (ID: ', p_new_category_id, ') 추가 완료.');
END IF; -- ID 범위 IF 종료
END IF; -- 이름 중복 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,53 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_add_group`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_group_name VARCHAR(100),
IN p_manager_user_id BIGINT, -- 파라미터명 변경됨
OUT p_new_group_id BIGINT,
OUT p_result_message VARCHAR(255)
)
COMMENT '그룹(부서) 추가 및 로그 기록'
BEGIN
DECLARE v_existing_group_id BIGINT DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_new_group_id = NULL; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_new_group_id = NULL; SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSEIF p_group_name IS NULL OR p_group_name = '' THEN
SET p_new_group_id = NULL; SET p_result_message = '그룹(부서) 이름은 필수입니다.';
ELSE
-- 그룹 이름 중복 검사
SELECT group_id INTO v_existing_group_id FROM group_info WHERE LOWER(group_name) = LOWER(p_group_name) LIMIT 1;
IF v_existing_group_id IS NOT NULL THEN
SET p_new_group_id = NULL; SET p_result_message = CONCAT('이미 사용 중인 그룹(부서) 이름입니다: ', p_group_name);
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO group_info (group_name, manager_user_id) -- 컬럼명 변경됨
VALUES (p_group_name, p_manager_user_id); -- 파라미터명 변경됨
SET p_new_group_id = LAST_INSERT_ID();
INSERT INTO log_add_group (log_date, admin_user_id, actor_description, group_id, group_name, manager_user_id) -- 컬럼명 변경됨
VALUES (v_now, p_admin_user_id, p_actor_description, p_new_group_id, p_group_name, p_manager_user_id); -- 파라미터명 변경됨
COMMIT;
SET p_result_message = CONCAT('그룹(부서) "', p_group_name, '" (ID: ', p_new_group_id, ') 추가 완료.');
END IF; -- 그룹 이름 중복 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,60 @@
DELIMITER $$
CREATE PROCEDURE `sp_add_resource`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_category_id TINYINT UNSIGNED,
IN p_resource_code VARCHAR(100),
IN p_manufacturer VARCHAR(100),
IN p_resource_name VARCHAR(100),
IN p_serial_num VARCHAR(200),
IN p_spec_value DECIMAL(10, 2),
IN p_spec_unit TINYINT UNSIGNED,
IN p_user_id BIGINT,
IN p_comments VARCHAR(200),
IN p_purchase_date DATE, -- 파라미터명 및 타입 변경
IN p_is_locked BOOLEAN,
OUT p_new_resource_id BIGINT
)
COMMENT '자산 추가 및 로그 기록'
BEGIN
DECLARE v_now DATETIME DEFAULT NOW(); -- register_date 용
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '작업 주체 정보(관리자 ID 또는 프로세스 설명)는 필수입니다.';
END IF;
IF p_resource_name IS NULL OR p_resource_name = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '제품명은 필수입니다.';
END IF;
IF p_serial_num IS NOT NULL AND p_serial_num != '' AND EXISTS (SELECT 1 FROM resource_info WHERE serial_num = p_serial_num) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '이미 등록된 시리얼 번호입니다.';
END IF;
-- 트랜잭션 시작
START TRANSACTION;
INSERT INTO resource_info (
category_id, resource_code, manufacturer, resource_name, serial_num,
spec_value, spec_unit, user_id, comments, purchase_date, register_date, is_locked
-- update_date는 ON UPDATE CURRENT_TIMESTAMP 로 자동 관리됨
) VALUES (
p_category_id, p_resource_code, p_manufacturer, p_resource_name, p_serial_num,
p_spec_value, p_spec_unit, p_user_id, p_comments, p_purchase_date, v_now, p_is_locked
);
SET p_new_resource_id = LAST_INSERT_ID();
INSERT INTO log_add_resource (
log_date, admin_user_id, actor_description, resource_id, category_id, resource_code,
manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments,
purchase_date, register_date -- 컬럼명 변경 반영
) VALUES (
v_now, p_admin_user_id, p_actor_description, p_new_resource_id, p_category_id, p_resource_code,
p_manufacturer, p_resource_name, p_serial_num, p_spec_value, p_spec_unit, p_user_id, p_comments,
p_purchase_date, v_now -- 컬럼명 변경 반영
);
COMMIT;
END
$$
DELIMITER ;

View File

@ -0,0 +1,62 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_add_user`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_display_name VARCHAR(100), -- 파라미터명 변경
IN p_account_name VARCHAR(255), -- 파라미터명 변경
IN p_group_id BIGINT,
OUT p_new_user_id BIGINT,
OUT p_result_message VARCHAR(255)
)
COMMENT '사용자 추가 및 로그 기록'
BEGIN
DECLARE v_existing_user_id BIGINT DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK;
SET p_new_user_id = NULL;
SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_new_user_id = NULL;
SET p_result_message = '작업 주체 정보는 필수입니다.';
-- RETURN; -- ★ 제거
ELSEIF p_account_name IS NULL OR p_account_name = '' THEN
SET p_new_user_id = NULL;
SET p_result_message = '계정 이름은 필수입니다.';
-- RETURN; -- ★ 제거
ELSE
-- 계정 이름 중복 검사
SELECT user_id INTO v_existing_user_id FROM user_info WHERE LOWER(account_name) = LOWER(p_account_name) LIMIT 1;
IF v_existing_user_id IS NOT NULL THEN
SET p_new_user_id = NULL;
SET p_result_message = CONCAT('이미 사용 중인 계정 이름입니다: ', p_account_name);
-- RETURN; -- ★ 제거
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO user_info (display_name, account_name, group_id)
VALUES (p_display_name, p_account_name, p_group_id);
SET p_new_user_id = LAST_INSERT_ID();
INSERT INTO log_add_user (log_date, admin_user_id, actor_description, user_id, display_name, account_name, group_id)
VALUES (v_now, p_admin_user_id, p_actor_description, p_new_user_id, p_display_name, p_account_name, p_group_id);
COMMIT;
SET p_result_message = CONCAT('사용자 "', IFNULL(p_display_name, p_account_name), '" (ID: ', p_new_user_id, ') 추가 완료.');
END IF; -- 계정 중복 검사 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,53 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_delete_category`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_category_id TINYINT UNSIGNED,
OUT p_result_message VARCHAR(255)
)
COMMENT '카테고리 삭제 및 로그 기록 (사용 자산 확인 포함)'
BEGIN
DECLARE v_category_name VARCHAR(40);
DECLARE v_asset_count INT DEFAULT 0;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSE
-- 삭제 대상 정보 조회
SELECT category_name INTO v_category_name FROM resource_category WHERE category_id = p_category_id;
IF v_category_name IS NULL THEN
SET p_result_message = CONCAT('삭제할 카테고리를 찾을 수 없습니다 (ID: ', p_category_id, ')');
ELSE
-- 사용 중인 자산 확인
SELECT COUNT(*) INTO v_asset_count FROM resource_info WHERE category_id = p_category_id;
IF v_asset_count > 0 THEN
SET p_result_message = CONCAT('카테고리 "', v_category_name, '"를 사용하는 자산 ', v_asset_count, '개가 있어 삭제할 수 없습니다. 자산 카테고리를 먼저 변경하세요.');
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO log_delete_category (log_date, admin_user_id, actor_description, category_id, category_name)
VALUES (v_now, p_admin_user_id, p_actor_description, p_category_id, v_category_name);
DELETE FROM resource_category WHERE category_id = p_category_id;
COMMIT;
SET p_result_message = CONCAT('카테고리 "', v_category_name, '" (ID: ', p_category_id, ') 삭제 완료.');
END IF; -- 자산 확인 IF 종료
END IF; -- 카테고리 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,55 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_delete_group`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_group_id BIGINT,
OUT p_result_message VARCHAR(255)
)
COMMENT '그룹(부서) 삭제 및 로그 기록 (멤버 확인 포함)'
BEGIN
DECLARE v_group_name VARCHAR(100);
DECLARE v_manager_user_id BIGINT; -- 변수명 변경
DECLARE v_member_count INT DEFAULT 0;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSE
-- 삭제 대상 정보 조회
SELECT group_name, manager_user_id INTO v_group_name, v_manager_user_id -- 컬럼명/변수명 변경
FROM group_info WHERE group_id = p_group_id;
IF v_group_name IS NULL THEN
SET p_result_message = CONCAT('삭제할 그룹(부서)을 찾을 수 없습니다 (ID: ', p_group_id, ')');
ELSE
-- 소속된 사용자 확인
SELECT COUNT(*) INTO v_member_count FROM user_info WHERE group_id = p_group_id;
IF v_member_count > 0 THEN
SET p_result_message = CONCAT('그룹(부서) "', v_group_name, '"에 속한 사용자 ', v_member_count, '명이 있어 삭제할 수 없습니다. 사용자 소속을 먼저 변경하세요.');
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO log_delete_group (log_date, admin_user_id, actor_description, group_id, group_name, manager_user_id) -- 컬럼명 변경
VALUES (v_now, p_admin_user_id, p_actor_description, p_group_id, v_group_name, v_manager_user_id); -- 변수명 변경
DELETE FROM group_info WHERE group_id = p_group_id;
COMMIT;
SET p_result_message = CONCAT('그룹(부서) "', v_group_name, '" (ID: ', p_group_id, ') 삭제 완료.');
END IF; -- 멤버 확인 IF 종료
END IF; -- 그룹 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,44 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_delete_resource`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_resource_id BIGINT
)
COMMENT '자산 삭제 및 로그 기록'
BEGIN
DECLARE v_now DATETIME DEFAULT NOW();
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '작업 주체 정보(관리자 ID 또는 프로세스 설명)는 필수입니다.';
END IF;
IF NOT EXISTS (SELECT 1 FROM resource_info WHERE resource_id = p_resource_id) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '삭제할 자산을 찾을 수 없습니다.';
END IF;
-- 트랜잭션 시작
START TRANSACTION;
-- 로그 기록 (삭제 전에!)
INSERT INTO log_delete_resource (
log_date, admin_user_id, actor_description, resource_id, category_id, resource_code,
manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments,
purchase_date, register_date -- 컬럼명 변경 반영
)
SELECT
v_now, p_admin_user_id, p_actor_description, resource_id, category_id, resource_code,
manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments,
purchase_date, register_date -- 컬럼명 변경 반영
FROM resource_info WHERE resource_id = p_resource_id;
-- 자산 삭제
DELETE FROM resource_info WHERE resource_id = p_resource_id;
COMMIT;
END
$$
DELIMITER ;

View File

@ -0,0 +1,62 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_delete_user`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_user_id BIGINT,
OUT p_result_message VARCHAR(255)
)
COMMENT '사용자 삭제 및 로그 기록 (할당 자산 확인 포함)'
BEGIN
DECLARE v_display_name VARCHAR(100);
DECLARE v_account_name VARCHAR(255);
DECLARE v_group_id BIGINT;
DECLARE v_assigned_assets_count INT DEFAULT 0;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
-- RETURN; -- ★ 제거
ELSE
-- 삭제 대상 정보 조회 및 존재 확인
SELECT display_name, account_name, group_id INTO v_display_name, v_account_name, v_group_id
FROM user_info WHERE user_id = p_user_id;
IF v_account_name IS NULL THEN
SET p_result_message = CONCAT('삭제할 사용자를 찾을 수 없습니다 (ID: ', p_user_id, ')');
-- RETURN; -- ★ 제거
ELSE
-- 할당된 자산 확인
SELECT COUNT(*) INTO v_assigned_assets_count FROM resource_info WHERE user_id = p_user_id;
IF v_assigned_assets_count > 0 THEN
SET p_result_message = CONCAT('사용자 "', IFNULL(v_display_name, v_account_name), '"에게 할당된 자산 ', v_assigned_assets_count, '개가 있어 삭제할 수 없습니다. 자산 할당을 먼저 해제하세요.');
-- RETURN; -- ★ 제거
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
INSERT INTO log_delete_user (log_date, admin_user_id, actor_description, user_id,
display_name, account_name, group_id)
VALUES (v_now, p_admin_user_id, p_actor_description, p_user_id,
v_display_name, v_account_name, v_group_id);
DELETE FROM user_info WHERE user_id = p_user_id;
COMMIT;
SET p_result_message = CONCAT('사용자 "', IFNULL(v_display_name, v_account_name), '" (ID: ', p_user_id, ') 삭제 완료.');
END IF; -- 자산 확인 IF 종료
END IF; -- 사용자 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,16 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_all_categories`()
COMMENT '모든 자산 카테고리 목록 조회 (이름순)'
BEGIN
SELECT category_id, category_name
FROM resource_category
ORDER BY category_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,23 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_all_groups`()
COMMENT '모든 그룹(부서) 목록 조회 (관리자 이름 포함, 이름순)'
BEGIN
SELECT
g.group_id,
g.group_name,
g.manager_user_id,
-- 관리자 표시 이름 생성 (user_list 프로시저와 유사하게)
CASE
WHEN m.user_id IS NOT NULL AND m.display_name IS NOT NULL AND m.display_name != '' AND m.account_name IS NOT NULL THEN CONCAT(m.display_name, ' [', m.account_name, ']')
WHEN m.display_name IS NOT NULL AND m.display_name != '' THEN m.display_name
WHEN m.account_name IS NOT NULL THEN m.account_name
ELSE NULL -- 매니저 없는 경우
END AS manager_display_name
FROM group_info g
LEFT JOIN user_info m ON g.manager_user_id = m.user_id -- user_info 와 조인
ORDER BY g.group_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,67 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_all_resources`(
IN p_page_num INT,
IN p_page_size INT,
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_category_id TINYINT UNSIGNED,
IN p_group_id BIGINT,
IN p_user_id BIGINT
)
COMMENT '전체 자산 목록 조회 (페이징, 정렬, 필터링)'
BEGIN
DECLARE v_offset INT;
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_sql TEXT;
-- 입력값 기본 처리
IF UPPER(p_sort_direction) != 'ASC' THEN SET p_sort_direction = 'DESC'; END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 정렬 기준 설정
SET v_order_by_clause = CASE p_sort_column
WHEN 'id' THEN CONCAT('ORDER BY r.resource_id ', p_sort_direction)
WHEN 'name' THEN CONCAT('ORDER BY r.resource_name ', p_sort_direction)
WHEN 'category' THEN CONCAT('ORDER BY rc.category_name ', p_sort_direction)
WHEN 'code' THEN CONCAT('ORDER BY r.resource_code ', p_sort_direction)
WHEN 'user' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'serial' THEN CONCAT('ORDER BY r.serial_num ', p_sort_direction)
WHEN 'purchased' THEN CONCAT('ORDER BY r.purchase_date ', p_sort_direction) -- 정렬 기준 변경: created -> purchased
WHEN 'registered' THEN CONCAT('ORDER BY r.register_date ', p_sort_direction) -- 정렬 기준 추가: registered
WHEN 'updated' THEN CONCAT('ORDER BY r.update_date ', p_sort_direction)
WHEN 'is_locked' THEN CONCAT('ORDER BY r.is_locked ', p_sort_direction)
ELSE 'ORDER BY r.resource_id DESC'
END;
IF p_sort_column != 'id' THEN SET v_order_by_clause = CONCAT(v_order_by_clause, ', r.resource_id DESC'); END IF;
-- 동적 SQL 생성
SET v_sql = CONCAT(
'SELECT SQL_CALC_FOUND_ROWS ',
' r.resource_id, r.category_id, rc.category_name, r.resource_code, r.manufacturer, ',
' r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, ',
' CASE WHEN u.user_id IS NOT NULL AND u.display_name IS NOT NULL AND u.display_name != \'\' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, \' [\', u.account_name, \']\') WHEN u.display_name IS NOT NULL AND u.display_name != \'\' THEN u.display_name ELSE u.account_name END AS user_display_name, ', -- 사용자 표시 이름 로직 변경
' g.group_name, r.comments, r.purchase_date, r.register_date, r.update_date, r.is_locked ', -- 컬럼명 변경 반영
'FROM resource_info r ',
' LEFT JOIN resource_category rc ON r.category_id = rc.category_id ',
' LEFT JOIN user_info u ON r.user_id = u.user_id ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
'WHERE (? IS NULL OR r.category_id = ?) ',
' AND (? IS NULL OR g.group_id = ?) ',
' AND (? IS NULL OR r.user_id = ?) ',
v_order_by_clause,
' LIMIT ? OFFSET ?'
);
-- SQL 실행
PREPARE stmt FROM v_sql;
EXECUTE stmt USING p_category_id, p_category_id, p_group_id, p_group_id, p_user_id, p_user_id, p_page_size, v_offset;
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,71 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_all_resources_export`(
-- 페이징 파라미터 제거
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_category_id TINYINT UNSIGNED,
IN p_group_id BIGINT,
IN p_user_id BIGINT
)
COMMENT '전체 자산 목록 조회 (내보내기용 - 페이징 없음, 잠금 상태 포함)'
BEGIN
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_sql TEXT;
IF UPPER(p_sort_direction) NOT IN ('ASC', 'DESC') THEN SET p_sort_direction = 'DESC'; END IF;
-- 정렬 기준 설정 (기존과 동일, is_locked 포함)
SET v_order_by_clause = CASE p_sort_column
WHEN 'id' THEN CONCAT('ORDER BY r.resource_id ', p_sort_direction)
WHEN 'name' THEN CONCAT('ORDER BY r.resource_name ', p_sort_direction)
WHEN 'category' THEN CONCAT('ORDER BY rc.category_name ', p_sort_direction)
WHEN 'code' THEN CONCAT('ORDER BY r.resource_code ', p_sort_direction)
WHEN 'user' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'serial' THEN CONCAT('ORDER BY r.serial_num ', p_sort_direction)
WHEN 'purchased' THEN CONCAT('ORDER BY r.purchase_date ', p_sort_direction)
WHEN 'registered' THEN CONCAT('ORDER BY r.register_date ', p_sort_direction)
WHEN 'updated' THEN CONCAT('ORDER BY r.update_date ', p_sort_direction)
WHEN 'is_locked' THEN CONCAT('ORDER BY r.is_locked ', p_sort_direction)
ELSE CONCAT('ORDER BY r.resource_id ', p_sort_direction)
END;
IF p_sort_column != 'id' THEN
SET v_order_by_clause = CONCAT(v_order_by_clause, ', r.resource_id DESC');
END IF;
SET v_sql = CONCAT(
'SELECT ', -- SQL_CALC_FOUND_ROWS 제거 (총 개수 필요 없음)
' r.resource_id, r.category_id, rc.category_name, r.resource_code, r.manufacturer, ',
' r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, ',
' CASE ',
' WHEN u.user_id IS NOT NULL AND u.display_name IS NOT NULL AND u.display_name != \'\' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, \' [\', u.account_name, \']\') ',
' WHEN u.display_name IS NOT NULL AND u.display_name != \'\' THEN u.display_name ',
' ELSE u.account_name ',
' END AS user_display_name, ',
' g.group_name, r.comments, r.purchase_date, r.register_date, r.update_date, r.is_locked ',
'FROM resource_info r ',
' LEFT JOIN resource_category rc ON r.category_id = rc.category_id ',
' LEFT JOIN user_info u ON r.user_id = u.user_id ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
'WHERE (CAST(? AS SIGNED) IS NULL OR r.category_id = ?) ',
' AND (CAST(? AS SIGNED) IS NULL OR g.group_id = ?) ',
' AND (CAST(? AS SIGNED) IS NULL OR r.user_id = ?) ',
v_order_by_clause
-- LIMIT ... OFFSET ... 제거
);
SET @p_category_id_filter = p_category_id;
SET @p_group_id_filter = p_group_id;
SET @p_user_id_filter = p_user_id;
PREPARE stmt FROM v_sql;
EXECUTE stmt USING
@p_category_id_filter, @p_category_id_filter,
@p_group_id_filter, @p_group_id_filter,
@p_user_id_filter, @p_user_id_filter;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,23 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_all_users`()
COMMENT '모든 사용자 목록 간략 조회 (폼 선택용)'
BEGIN
SELECT
user_id,
-- 표시 이름 형식: "표시이름 [계정명]" 또는 "표시이름" 또는 "계정명"
CASE
WHEN display_name IS NOT NULL AND display_name != '' AND account_name IS NOT NULL THEN CONCAT(display_name, ' [', account_name, ']')
WHEN display_name IS NOT NULL AND display_name != '' THEN display_name
ELSE account_name
END AS user_display_name
FROM user_info
ORDER BY user_display_name;
END
$$
DELIMITER ;

View File

@ -0,0 +1,21 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_assets_count_by_category`()
COMMENT '카테고리별 자산 수 조회 (대시보드용)'
BEGIN
SELECT
rc.category_id,
rc.category_name,
COUNT(r.resource_id) AS asset_count
FROM resource_category rc
LEFT JOIN resource_info r ON rc.category_id = r.category_id
GROUP BY rc.category_id, rc.category_name
ORDER BY rc.category_name;
END
$$
DELIMITER ;

View File

@ -0,0 +1,100 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_category_audit_logs`(
IN p_search_term VARCHAR(100), -- 검색어 (NULL 가능)
IN p_start_date DATE, -- 시작일 (NULL 가능)
IN p_end_date DATE, -- 종료일 (NULL 가능)
IN p_page_num INT, -- 페이지 번호 (기본값 1)
IN p_page_size INT -- 페이지 크기 (기본값 20)
)
COMMENT '카테고리 관련 감사 로그 통합 조회 (검색, 기간, 페이징)'
BEGIN
DECLARE v_offset INT;
SET @v_search_like = NULL;
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN
SET @v_search_like = CONCAT('%', p_search_term, '%');
END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 날짜 범위 조건 문자열 동적 생성
SET @v_date_condition = '';
IF p_start_date IS NOT NULL THEN
SET @v_date_condition = CONCAT('AND l.log_date >= DATE(''', p_start_date, ''') ');
END IF;
IF p_end_date IS NOT NULL THEN
SET @v_date_condition = CONCAT(@v_date_condition, 'AND l.log_date < DATE_ADD(DATE(''', p_end_date, '''), INTERVAL 1 DAY) ');
END IF;
-- 검색 조건 문자열 동적 생성 (통합 결과셋 대상)
SET @v_search_condition = '';
IF @v_search_like IS NOT NULL THEN
SET @v_search_condition = CONCAT(
'WHERE (',
' actor_info LIKE @v_search_like ', -- 작업자 정보
' OR CAST(target_id AS CHAR) LIKE @v_search_like ', -- 대상 카테고리 ID
' OR target_info_at_log LIKE @v_search_like ', -- 대상 카테고리 정보 (이름)
' OR details LIKE @v_search_like', -- 상세 내용
') '
);
ELSE
SET @v_search_condition = 'WHERE 1=1 ';
END IF;
-- 최종 동적 SQL 구성
SET @v_sql = CONCAT('
SELECT SQL_CALC_FOUND_ROWS * FROM (
-- 카테고리 추가 로그
SELECT
\'ADD\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.category_id AS target_id,
l.category_name AS target_info_at_log, -- 추가 시점 카테고리 이름
CONCAT(\' : \', l.category_name, \' (ID: \', l.category_id, \')\') AS details
FROM log_add_category l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 카테고리 수정 로그
SELECT
\'UPDATE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.category_id AS target_id,
l.new_category_name AS target_info_at_log, -- 수정 후 카테고리 이름
CONCAT(\' : \', COALESCE(l.old_category_name, \'\'), \'->\', l.new_category_name, \' (ID: \', l.category_id, \')\') AS details
FROM log_update_category l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 카테고리 삭제 로그
SELECT
\'DELETE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.category_id AS target_id,
l.category_name AS target_info_at_log, -- 삭제 시점 카테고리 이름
CONCAT(\' : \', l.category_name, \' (ID: \', l.category_id, \')\') AS details
FROM log_delete_category l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
) AS combined_logs
', @v_search_condition, '
ORDER BY log_date DESC
LIMIT ? OFFSET ?
');
-- SQL 문 실행
PREPARE stmt FROM @v_sql;
EXECUTE stmt USING p_page_size, v_offset;
-- 전체 결과 수 계산 값 반환
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,18 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_category_by_id`(
IN p_category_id TINYINT UNSIGNED
)
COMMENT '카테고리 ID로 정보 조회'
BEGIN
SELECT category_id, category_name
FROM resource_category
WHERE category_id = p_category_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,18 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_dashboard_summary`()
COMMENT '대시보드 요약 정보 조회 (총 자산, 사용자, 그룹, 미할당 자산 수)'
BEGIN
SELECT
(SELECT COUNT(*) FROM resource_info) AS total_assets,
(SELECT COUNT(*) FROM user_info) AS total_users,
(SELECT COUNT(*) FROM group_info) AS total_groups,
(SELECT COUNT(*) FROM resource_info WHERE user_id IS NULL) AS unassigned_assets;
END
$$
DELIMITER ;

View File

@ -0,0 +1,103 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_group_audit_logs`(
IN p_search_term VARCHAR(100), -- 검색어 (NULL 가능)
IN p_start_date DATE, -- 시작일 (NULL 가능)
IN p_end_date DATE, -- 종료일 (NULL 가능)
IN p_page_num INT, -- 페이지 번호 (기본값 1)
IN p_page_size INT -- 페이지 크기 (기본값 20)
)
COMMENT '그룹(부서) 관련 감사 로그 통합 조회 (검색, 기간, 페이징)'
BEGIN
DECLARE v_offset INT;
SET @v_search_like = NULL;
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN
SET @v_search_like = CONCAT('%', p_search_term, '%');
END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 날짜 범위 조건 문자열 동적 생성
SET @v_date_condition = '';
IF p_start_date IS NOT NULL THEN
SET @v_date_condition = CONCAT('AND l.log_date >= DATE(''', p_start_date, ''') ');
END IF;
IF p_end_date IS NOT NULL THEN
SET @v_date_condition = CONCAT(@v_date_condition, 'AND l.log_date < DATE_ADD(DATE(''', p_end_date, '''), INTERVAL 1 DAY) ');
END IF;
-- 검색 조건 문자열 동적 생성 (통합 결과셋 대상)
SET @v_search_condition = '';
IF @v_search_like IS NOT NULL THEN
SET @v_search_condition = CONCAT(
'WHERE (',
' actor_info LIKE @v_search_like ', -- 작업자 정보
' OR CAST(target_id AS CHAR) LIKE @v_search_like ', -- 대상 그룹 ID
' OR target_info_at_log LIKE @v_search_like ', -- 대상 그룹 정보 (이름)
' OR details LIKE @v_search_like', -- 상세 내용
') '
);
ELSE
SET @v_search_condition = 'WHERE 1=1 ';
END IF;
-- 최종 동적 SQL 구성
SET @v_sql = CONCAT('
SELECT SQL_CALC_FOUND_ROWS * FROM (
-- 그룹 추가 로그
SELECT
\'ADD\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.group_id AS target_id,
l.group_name AS target_info_at_log, -- 추가 시점 그룹 이름
CONCAT(\' : \', l.group_name, IF(l.manager_user_id IS NULL, \'\', CONCAT(\' ( ID: \', l.manager_user_id, \')\'))) AS details
FROM log_add_group l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 그룹 수정 로그
SELECT
\'UPDATE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.group_id AS target_id,
l.new_group_name AS target_info_at_log, -- 수정 후 그룹 이름
CONCAT(\' : \', l.new_group_name, \'. \',
IF(l.old_group_name <=> l.new_group_name, \'\', CONCAT(\' : \', COALESCE(l.old_group_name, \'\'), \'->\', l.new_group_name, \'. \')),
IF(l.old_manager_user_id <=> l.new_manager_user_id, \'\', CONCAT(\' : \', COALESCE(l.old_manager_user_id, \'\'), \'->\', COALESCE(l.new_manager_user_id, \'\'), \'. \'))
) AS details
FROM log_update_group l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 그룹 삭제 로그
SELECT
\'DELETE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.group_id AS target_id,
l.group_name AS target_info_at_log, -- 삭제 시점 그룹 이름
CONCAT(\' : \', l.group_name) AS details
FROM log_delete_group l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
) AS combined_logs
', @v_search_condition, '
ORDER BY log_date DESC
LIMIT ? OFFSET ?
');
-- SQL 문 실행
PREPARE stmt FROM @v_sql;
EXECUTE stmt USING p_page_size, v_offset;
-- 전체 결과 수 계산 값 반환
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,24 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_group_by_id`(
IN p_group_id BIGINT
)
COMMENT '그룹(부서) ID로 상세 정보 조회 (관리자 정보 포함)'
BEGIN
SELECT
g.group_id,
g.group_name,
g.manager_user_id, -- 컬럼명 변경됨
u.display_name AS manager_display_name, -- 관리자 표시 이름
u.account_name AS manager_account_name -- 관리자 계정 이름
FROM group_info g
LEFT JOIN user_info u ON g.manager_user_id = u.user_id -- 조인 컬럼 변경됨
WHERE g.group_id = p_group_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,114 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_resource_audit_logs`(
IN p_search_term VARCHAR(100), -- 검색어 (NULL 가능)
IN p_start_date DATE, -- 시작일 (NULL 가능)
IN p_end_date DATE, -- 종료일 (NULL 가능)
IN p_page_num INT, -- 페이지 번호 (기본값 1)
IN p_page_size INT -- 페이지 크기 (기본값 20)
)
COMMENT '자산 관련 감사 로그 통합 조회 (검색, 기간, 페이징)'
BEGIN
DECLARE v_offset INT;
SET @v_search_like = NULL; -- 검색어용 세션 변수
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN
SET @v_search_like = CONCAT('%', p_search_term, '%');
END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 날짜 범위 조건 문자열 동적 생성
SET @v_date_condition = '';
IF p_start_date IS NOT NULL THEN
SET @v_date_condition = CONCAT('AND l.log_date >= DATE(''', p_start_date, ''') '); -- DATE() 사용하여 시간 무시
END IF;
IF p_end_date IS NOT NULL THEN
-- 종료일 다음 날 0시 미만으로 포함
SET @v_date_condition = CONCAT(@v_date_condition, 'AND l.log_date < DATE_ADD(DATE(''', p_end_date, '''), INTERVAL 1 DAY) ');
END IF;
-- 검색 조건 문자열 동적 생성 (통합 결과셋 대상)
SET @v_search_condition = '';
IF @v_search_like IS NOT NULL THEN
SET @v_search_condition = CONCAT(
'WHERE (',
' actor_info LIKE @v_search_like ', -- 작업자 정보
' OR CAST(target_id AS CHAR) LIKE @v_search_like ', -- 대상 ID (문자열로 변환하여 검색)
' OR target_info_at_log LIKE @v_search_like ', -- 대상 정보 (이름 등)
' OR serial_num LIKE @v_search_like ', -- 시리얼 번호
' OR details LIKE @v_search_like', -- 상세 내용
') '
);
ELSE
SET @v_search_condition = 'WHERE 1=1 '; -- 검색어 없으면 모든 결과
END IF;
-- 최종 동적 SQL 구성
-- 1. 각 로그 테이블에서 기간 필터링 적용하여 UNION ALL
-- 2. UNION ALL 결과셋에 대해 검색어 필터링 적용
-- 3. 정렬, 페이징 적용
SET @v_sql = CONCAT('
SELECT SQL_CALC_FOUND_ROWS * FROM (
-- 자산 추가 로그
SELECT
\'ADD\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.resource_id AS target_id,
l.resource_name AS target_info_at_log,
l.serial_num,
CONCAT(\' : \', l.resource_name, \' (SN:\', IFNULL(l.serial_num, \'-\'), \')\') AS details
FROM log_add_resource l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 자산 수정 로그
SELECT
\'UPDATE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.resource_id AS target_id,
l.resource_name AS target_info_at_log, -- 변경 후 이름
l.serial_num AS serial_num, -- 변경 후 시리얼
-- 상세 내용 생성 (예시: 변경된 필드 표시 - 필요시 복잡하게 구현 가능)
CONCAT(
\' : \', IFNULL(l.resource_name, \'( )\'),
\' (ID:\', l.resource_id, \')\'
-- 여기에 변경된 필드 정보 추가 가능 (예: IF(old_value!=new_value, ...))
) AS details
FROM log_update_resource l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 자산 삭제 로그
SELECT
\'DELETE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.resource_id AS target_id,
l.resource_name AS target_info_at_log, -- 삭제 시점 이름
l.serial_num AS serial_num, -- 삭제 시점 시리얼
CONCAT(\' : \', l.resource_name, \' (SN:\', IFNULL(l.serial_num, \'-\'), \')\') AS details
FROM log_delete_resource l LEFT JOIN auth_user au ON l.admin_user_id = au.id
WHERE 1=1 ', @v_date_condition, '
) AS combined_logs
', @v_search_condition, ' -- 최종 검색 조건 적용
ORDER BY log_date DESC
LIMIT ? OFFSET ? -- 페이징 적용
');
-- SQL 문 실행
PREPARE stmt FROM @v_sql;
-- LIMIT 절에 파라미터 바인딩
EXECUTE stmt USING p_page_size, v_offset;
-- 전체 결과 수 계산 값 반환 (두 번째 결과셋)
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,21 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_resource_by_id`(
IN p_resource_id BIGINT
)
COMMENT '자산 ID로 상세 정보 조회'
BEGIN
SELECT
r.resource_id, r.category_id, rc.category_name, r.resource_code, r.manufacturer,
r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id,
CASE WHEN u.user_id IS NOT NULL AND u.display_name IS NOT NULL AND u.display_name != '' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, ' [', u.account_name, ']') WHEN u.display_name IS NOT NULL AND u.display_name != '' THEN u.display_name ELSE u.account_name END AS user_display_name, -- 사용자 표시 이름 로직 변경
g.group_name, r.comments, r.purchase_date, r.register_date, r.update_date, r.is_locked -- 컬럼명 변경 반영
FROM resource_info r
LEFT JOIN resource_category rc ON r.category_id = rc.category_id
LEFT JOIN user_info u ON r.user_id = u.user_id
LEFT JOIN group_info g ON u.group_id = g.group_id
WHERE r.resource_id = p_resource_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,31 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_resources_by_account`( -- 이름 변경
IN p_account_name VARCHAR(255) -- 파라미터명 변경
)
COMMENT '사용자 계정명으로 할당된 자원 목록 조회 (간단 버전)'
BEGIN
DECLARE v_user_id BIGINT DEFAULT NULL;
-- 계정 이름으로 사용자 ID 찾기
SELECT user_id INTO v_user_id
FROM user_info WHERE LOWER(account_name) = LOWER(p_account_name) LIMIT 1; -- 컬럼명 변경
-- 사용자가 존재하면 해당 사용자의 자산 목록 반환
IF v_user_id IS NOT NULL THEN
SELECT r.resource_id, r.resource_name, r.serial_num
FROM resource_info r
WHERE r.user_id = v_user_id
ORDER BY r.register_date; -- 정렬 기준 변경: create_date -> register_date
ELSE
-- 사용자가 없으면 빈 결과 반환
SELECT NULL AS resource_id, NULL AS resource_name, NULL AS serial_num WHERE FALSE;
END IF;
END
$$
DELIMITER ;

View File

@ -0,0 +1,71 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_resources_by_search`(
IN p_search_term VARCHAR(100),
IN p_page_num INT,
IN p_page_size INT,
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_category_id TINYINT UNSIGNED,
IN p_group_id BIGINT,
IN p_user_id BIGINT
)
COMMENT '자산 검색 결과 조회 (페이징, 정렬, 필터링)'
BEGIN
DECLARE v_offset INT;
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_sql TEXT;
SET @p_search_like = NULL; -- 세션 변수 사용
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN SET @p_search_like = CONCAT('%', p_search_term, '%'); END IF;
IF UPPER(p_sort_direction) != 'ASC' THEN SET p_sort_direction = 'DESC'; END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 정렬 기준 설정
SET v_order_by_clause = CASE p_sort_column
WHEN 'id' THEN CONCAT('ORDER BY r.resource_id ', p_sort_direction)
WHEN 'name' THEN CONCAT('ORDER BY r.resource_name ', p_sort_direction)
WHEN 'category' THEN CONCAT('ORDER BY rc.category_name ', p_sort_direction)
WHEN 'code' THEN CONCAT('ORDER BY r.resource_code ', p_sort_direction)
WHEN 'user' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'serial' THEN CONCAT('ORDER BY r.serial_num ', p_sort_direction)
WHEN 'purchased' THEN CONCAT('ORDER BY r.purchase_date ', p_sort_direction) -- 정렬 기준 변경
WHEN 'registered' THEN CONCAT('ORDER BY r.register_date ', p_sort_direction) -- 정렬 기준 추가
WHEN 'updated' THEN CONCAT('ORDER BY r.update_date ', p_sort_direction)
WHEN 'is_locked' THEN CONCAT('ORDER BY r.is_locked ', p_sort_direction)
ELSE 'ORDER BY r.resource_id DESC'
END;
IF p_sort_column != 'id' THEN SET v_order_by_clause = CONCAT(v_order_by_clause, ', r.resource_id DESC'); END IF;
-- 동적 SQL 생성
SET v_sql = CONCAT(
'SELECT SQL_CALC_FOUND_ROWS ',
' r.resource_id, r.category_id, rc.category_name, r.resource_code, r.manufacturer, ',
' r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, ',
' CASE WHEN u.user_id IS NOT NULL AND u.display_name IS NOT NULL AND u.display_name != \'\' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, \' [\', u.account_name, \']\') WHEN u.display_name IS NOT NULL AND u.display_name != \'\' THEN u.display_name ELSE u.account_name END AS user_display_name, ', -- 사용자 표시 이름 로직 변경
' g.group_name, r.comments, r.purchase_date, r.register_date, r.update_date, r.is_locked ', -- 컬럼명 변경 반영
'FROM resource_info r ',
' LEFT JOIN resource_category rc ON r.category_id = rc.category_id ',
' LEFT JOIN user_info u ON r.user_id = u.user_id ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
'WHERE ((@p_search_like IS NULL) OR (r.resource_name LIKE @p_search_like OR r.serial_num LIKE @p_search_like OR r.resource_code LIKE @p_search_like OR u.display_name LIKE @p_search_like OR u.account_name LIKE @p_search_like OR r.manufacturer LIKE @p_search_like OR r.comments LIKE @p_search_like)) ', -- 검색 컬럼 변경
' AND (? IS NULL OR r.category_id = ?) ',
' AND (? IS NULL OR g.group_id = ?) ',
' AND (? IS NULL OR r.user_id = ?) ',
v_order_by_clause,
' LIMIT ? OFFSET ?'
);
-- SQL 실행
PREPARE stmt FROM v_sql;
EXECUTE stmt USING p_category_id, p_category_id, p_group_id, p_group_id, p_user_id, p_user_id, p_page_size, v_offset;
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,89 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_resources_by_search_export`(
IN p_search_term VARCHAR(100), -- ★★★ 검색어 입력 파라미터 ★★★
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_category_id TINYINT UNSIGNED,
IN p_group_id BIGINT,
IN p_user_id BIGINT
)
COMMENT '검색된 전체 자산 목록 조회 (내보내기용 - 페이징 없음, 잠금 상태 포함)'
BEGIN
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_sql TEXT;
DECLARE v_search_like_term VARCHAR(105); -- 검색어 앞뒤에 % 추가
IF UPPER(p_sort_direction) NOT IN ('ASC', 'DESC') THEN SET p_sort_direction = 'DESC'; END IF;
-- 정렬 기준 설정 (is_locked 포함)
SET v_order_by_clause = CASE p_sort_column
WHEN 'id' THEN CONCAT('ORDER BY r.resource_id ', p_sort_direction)
WHEN 'name' THEN CONCAT('ORDER BY r.resource_name ', p_sort_direction)
WHEN 'category' THEN CONCAT('ORDER BY rc.category_name ', p_sort_direction)
WHEN 'code' THEN CONCAT('ORDER BY r.resource_code ', p_sort_direction)
WHEN 'user' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'serial' THEN CONCAT('ORDER BY r.serial_num ', p_sort_direction)
WHEN 'purchased' THEN CONCAT('ORDER BY r.purchase_date ', p_sort_direction)
WHEN 'registered' THEN CONCAT('ORDER BY r.register_date ', p_sort_direction)
WHEN 'updated' THEN CONCAT('ORDER BY r.update_date ', p_sort_direction)
WHEN 'is_locked' THEN CONCAT('ORDER BY r.is_locked ', p_sort_direction)
ELSE CONCAT('ORDER BY r.resource_id ', p_sort_direction)
END;
IF p_sort_column != 'id' THEN
SET v_order_by_clause = CONCAT(v_order_by_clause, ', r.resource_id DESC');
END IF;
-- 검색어 LIKE 조건용 문자열 생성
SET v_search_like_term = IF(p_search_term IS NOT NULL AND p_search_term != '', CONCAT('%', p_search_term, '%'), NULL);
SET v_sql = CONCAT(
'SELECT ',
' r.resource_id, r.category_id, rc.category_name, r.resource_code, r.manufacturer, ',
' r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, ',
' CASE ',
' WHEN u.user_id IS NOT NULL AND u.display_name IS NOT NULL AND u.display_name != \'\' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, \' [\', u.account_name, \']\') ',
' WHEN u.display_name IS NOT NULL AND u.display_name != \'\' THEN u.display_name ',
' ELSE u.account_name ',
' END AS user_display_name, ',
' g.group_name, r.comments, r.purchase_date, r.register_date, r.update_date, r.is_locked ',
'FROM resource_info r ',
' LEFT JOIN resource_category rc ON r.category_id = rc.category_id ',
' LEFT JOIN user_info u ON r.user_id = u.user_id ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
'WHERE (CAST(? AS SIGNED) IS NULL OR r.category_id = ?) ', -- category_id 필터
' AND (CAST(? AS SIGNED) IS NULL OR g.group_id = ?) ', -- group_id 필터
' AND (CAST(? AS SIGNED) IS NULL OR r.user_id = ?) ', -- user_id 필터
' AND (? IS NULL OR ( ', -- ★★★ 검색어 조건 시작 (v_search_like_term 이 NULL이면 이 AND 조건 전체가 참이 됨) ★★★
' LOWER(r.resource_name) LIKE LOWER(?) OR ',
' LOWER(r.serial_num) LIKE LOWER(?) OR ',
' LOWER(r.resource_code) LIKE LOWER(?) OR ',
' (u.user_id IS NOT NULL AND LOWER(u.display_name) LIKE LOWER(?)) OR ', -- u.display_name 이 NULL 이 아닐 때만 검색
' (u.user_id IS NOT NULL AND LOWER(u.account_name) LIKE LOWER(?)) OR ', -- u.account_name 이 NULL 이 아닐 때만 검색
' LOWER(r.manufacturer) LIKE LOWER(?) OR ',
' LOWER(r.comments) LIKE LOWER(?) ',
' )) ', -- ★★★ 검색어 조건 끝 ★★★
v_order_by_clause
);
-- Prepared Statement 에 사용할 변수 설정
SET @p_category_id_param = p_category_id;
SET @p_group_id_param = p_group_id;
SET @p_user_id_param = p_user_id;
SET @p_search_term_param = v_search_like_term; -- %가 포함된 검색어 또는 NULL
PREPARE stmt FROM v_sql;
EXECUTE stmt USING
@p_category_id_param, @p_category_id_param,
@p_group_id_param, @p_group_id_param,
@p_user_id_param, @p_user_id_param,
@p_search_term_param, -- 검색어 NULL 체크용
@p_search_term_param, @p_search_term_param, @p_search_term_param, -- resource 관련 필드 검색
@p_search_term_param, @p_search_term_param, -- user 관련 필드 검색
@p_search_term_param, @p_search_term_param; -- manufacturer, comments 검색
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,115 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_user_audit_logs`(
IN p_search_term VARCHAR(100), -- 검색어 (NULL 가능)
IN p_start_date DATE, -- 시작일 (NULL 가능)
IN p_end_date DATE, -- 종료일 (NULL 가능)
IN p_page_num INT, -- 페이지 번호 (기본값 1)
IN p_page_size INT -- 페이지 크기 (기본값 20)
)
COMMENT '사용자 관련 감사 로그 통합 조회 (검색, 기간, 페이징)'
BEGIN
DECLARE v_offset INT;
SET @v_search_like = NULL; -- 검색어용 세션 변수
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN
SET @v_search_like = CONCAT('%', p_search_term, '%');
END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 날짜 범위 조건 문자열 동적 생성
SET @v_date_condition = '';
IF p_start_date IS NOT NULL THEN
SET @v_date_condition = CONCAT('AND l.log_date >= DATE(''', p_start_date, ''') ');
END IF;
IF p_end_date IS NOT NULL THEN
SET @v_date_condition = CONCAT(@v_date_condition, 'AND l.log_date < DATE_ADD(DATE(''', p_end_date, '''), INTERVAL 1 DAY) ');
END IF;
-- 검색 조건 문자열 동적 생성 (통합 결과셋 대상)
SET @v_search_condition = '';
IF @v_search_like IS NOT NULL THEN
SET @v_search_condition = CONCAT(
'WHERE (',
' actor_info LIKE @v_search_like ', -- 작업자 정보
' OR CAST(target_id AS CHAR) LIKE @v_search_like ', -- 대상 사용자 ID
' OR target_info_at_log LIKE @v_search_like ', -- 대상 사용자 정보 (이름, 계정)
' OR group_name_at_log LIKE @v_search_like ', -- 대상 부서 이름
' OR details LIKE @v_search_like', -- 상세 내용
') '
);
ELSE
SET @v_search_condition = 'WHERE 1=1 '; -- 검색어 없으면 모든 결과
END IF;
-- 최종 동적 SQL 구성
SET @v_sql = CONCAT('
SELECT SQL_CALC_FOUND_ROWS * FROM (
-- 사용자 추가 로그
SELECT
\'ADD\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.user_id AS target_id,
COALESCE(l.display_name, l.account_name) AS target_info_at_log, -- 추가 시점 정보
g.group_name AS group_name_at_log, -- 추가 시점 그룹 이름
CONCAT(\' : \', COALESCE(l.display_name, \'\'), \' (\', l.account_name, \')\') AS details
FROM log_add_user l
LEFT JOIN auth_user au ON l.admin_user_id = au.id
LEFT JOIN group_info g ON l.group_id = g.group_id
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 사용자 수정 로그
SELECT
\'UPDATE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.user_id AS target_id,
COALESCE(l.new_display_name, l.new_account_name) AS target_info_at_log, -- 수정 후 정보
g_new.group_name AS group_name_at_log, -- 수정 후 그룹 이름
CONCAT(\' : \', COALESCE(l.new_display_name, \'\'), \' (\', l.new_account_name, \'). \',
IF(l.old_display_name <=> l.new_display_name, \'\', CONCAT(\' : \', COALESCE(l.old_display_name, \'\'), \'->\', COALESCE(l.new_display_name, \'\'), \'. \')),
IF(l.old_account_name <=> l.new_account_name, \'\', CONCAT(\' : \', l.old_account_name, \'->\', l.new_account_name, \'. \')),
IF(l.old_group_id <=> l.new_group_id, \'\', CONCAT(\' : \', COALESCE(g_old.group_name, \'\'), \'->\', COALESCE(g_new.group_name, \'\'), \'. \'))
) AS details
FROM log_update_user l
LEFT JOIN auth_user au ON l.admin_user_id = au.id
LEFT JOIN group_info g_old ON l.old_group_id = g_old.group_id -- 변경 전 그룹 조인
LEFT JOIN group_info g_new ON l.new_group_id = g_new.group_id -- 변경 후 그룹 조인
WHERE 1=1 ', @v_date_condition, '
UNION ALL
-- 사용자 삭제 로그
SELECT
\'DELETE\' AS log_type, l.log_id, l.log_date,
COALESCE(au.username, l.actor_description, \'System/Unknown\') AS actor_info,
l.user_id AS target_id,
COALESCE(l.display_name, l.account_name) AS target_info_at_log, -- 삭제 시점 정보
g.group_name AS group_name_at_log, -- 삭제 시점 그룹 이름
CONCAT(\' : \', COALESCE(l.display_name, \'\'), \' (\', l.account_name, \')\') AS details
FROM log_delete_user l
LEFT JOIN auth_user au ON l.admin_user_id = au.id
LEFT JOIN group_info g ON l.group_id = g.group_id
WHERE 1=1 ', @v_date_condition, '
) AS combined_logs
', @v_search_condition, ' -- 최종 검색 조건 적용
ORDER BY log_date DESC
LIMIT ? OFFSET ? -- 페이징 적용
');
-- SQL 문 실행
PREPARE stmt FROM @v_sql;
EXECUTE stmt USING p_page_size, v_offset;
-- 전체 결과 수 계산 값 반환
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,24 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_user_by_id`(
IN p_user_id BIGINT
)
COMMENT '사용자 ID로 상세 정보 조회'
BEGIN
SELECT
u.user_id,
u.display_name, -- 컬럼명 변경
u.account_name, -- 컬럼명 변경
u.group_id,
g.group_name
FROM user_info u
LEFT JOIN group_info g ON u.group_id = g.group_id
WHERE u.user_id = p_user_id;
END
$$
DELIMITER ;

View File

@ -0,0 +1,80 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_get_user_list`(
IN p_search_term VARCHAR(100),
IN p_page_num INT,
IN p_page_size INT,
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_group_id BIGINT
)
COMMENT '사용자 목록 조회 (검색, 페이징, 정렬, 필터링, 자산 수 포함)'
BEGIN
DECLARE v_offset INT;
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_where_clause TEXT;
DECLARE v_sql TEXT;
SET @p_search_like = NULL; -- 세션 변수 사용 유지 (Prepared Statement 제약)
-- 입력값 기본 처리
IF p_search_term IS NOT NULL AND p_search_term != '' THEN SET @p_search_like = CONCAT('%', p_search_term, '%'); END IF;
IF UPPER(p_sort_direction) NOT IN ('ASC', 'DESC') THEN SET p_sort_direction = 'ASC'; END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 정렬 기준 설정
SET v_order_by_clause = CASE p_sort_column
WHEN 'name' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'account' THEN CONCAT('ORDER BY u.account_name ', p_sort_direction) -- 정렬 기준 변경: email -> account
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'assets' THEN CONCAT('ORDER BY assigned_asset_count ', p_sort_direction)
ELSE 'ORDER BY user_display_name ASC'
END;
IF p_sort_column != 'name' THEN SET v_order_by_clause = CONCAT(v_order_by_clause, ', u.user_id ASC'); END IF;
-- 검색 조건 설정
SET v_where_clause = 'WHERE 1=1 ';
IF @p_search_like IS NOT NULL THEN
SET v_where_clause = CONCAT(v_where_clause, 'AND (u.display_name LIKE @p_search_like OR u.account_name LIKE @p_search_like OR g.group_name LIKE @p_search_like) '); -- 검색 컬럼 변경
END IF;
IF p_group_id IS NOT NULL THEN
SET v_where_clause = CONCAT(v_where_clause, 'AND u.group_id = ? ');
END IF;
-- 동적 SQL 생성
SET v_sql = CONCAT(
'SELECT SQL_CALC_FOUND_ROWS ',
' u.user_id, ',
' CASE WHEN u.display_name IS NOT NULL AND u.display_name != \'\' AND u.account_name IS NOT NULL THEN CONCAT(u.display_name, \' [\', u.account_name, \']\') WHEN u.display_name IS NOT NULL AND u.display_name != \'\' THEN u.display_name ELSE u.account_name END AS user_display_name, ', -- 표시 이름 로직 변경
' u.account_name, ', -- 컬럼명 변경
' g.group_name, ',
' COUNT(r.resource_id) AS assigned_asset_count ',
'FROM user_info u ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
' LEFT JOIN resource_info r ON u.user_id = r.user_id ',
v_where_clause,
'GROUP BY u.user_id, u.display_name, u.account_name, g.group_name ', -- GROUP BY 컬럼 변경
v_order_by_clause,
' LIMIT ? OFFSET ?'
);
-- SQL 실행
PREPARE stmt FROM v_sql;
IF p_group_id IS NOT NULL THEN
EXECUTE stmt USING p_group_id, p_page_size, v_offset;
ELSE
EXECUTE stmt USING p_page_size, v_offset;
END IF;
-- 전체 개수 반환
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,74 @@
DELIMITER $$
CREATE PROCEDURE `sp_get_user_status_list`(
IN p_search_term VARCHAR(100),
IN p_page_num INT,
IN p_page_size INT,
IN p_sort_column VARCHAR(50),
IN p_sort_direction VARCHAR(4),
IN p_group_id BIGINT
)
BEGIN
DECLARE v_offset INT;
DECLARE v_order_by_clause VARCHAR(255);
DECLARE v_where_clause TEXT;
DECLARE v_sql TEXT;
SET @p_search_like = NULL;
IF p_search_term IS NOT NULL AND p_search_term != '' THEN
SET @p_search_like = CONCAT('%', p_search_term, '%');
END IF;
IF UPPER(p_sort_direction) NOT IN ('ASC', 'DESC') THEN SET p_sort_direction = 'ASC'; END IF;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 20; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
SET v_order_by_clause = CASE p_sort_column
WHEN 'name' THEN CONCAT('ORDER BY user_display_name ', p_sort_direction)
WHEN 'email' THEN CONCAT('ORDER BY u.email_address ', p_sort_direction)
WHEN 'group' THEN CONCAT('ORDER BY g.group_name ', p_sort_direction)
WHEN 'assets' THEN CONCAT('ORDER BY assigned_asset_count ', p_sort_direction)
ELSE 'ORDER BY user_display_name ASC'
END;
IF p_sort_column != 'name' THEN
SET v_order_by_clause = CONCAT(v_order_by_clause, ', u.user_id ASC');
END IF;
SET v_where_clause = 'WHERE 1=1 ';
IF @p_search_like IS NOT NULL THEN
SET v_where_clause = CONCAT(v_where_clause, 'AND (u.user_name LIKE @p_search_like OR u.email_address LIKE @p_search_like OR g.group_name LIKE @p_search_like) ');
END IF;
IF p_group_id IS NOT NULL THEN
SET v_where_clause = CONCAT(v_where_clause, 'AND u.group_id = ? ');
END IF;
SET v_sql = CONCAT(
'SELECT SQL_CALC_FOUND_ROWS ',
' u.user_id, ',
' CASE WHEN u.user_name IS NOT NULL AND u.email_address IS NOT NULL THEN CONCAT(u.user_name, \' [\', LOWER(SUBSTRING_INDEX(u.email_address, \'@\', 1)), \']\') WHEN u.user_name IS NOT NULL THEN u.user_name ELSE u.email_address END AS user_display_name, ',
' u.email_address, ',
' g.group_name, ',
' COUNT(r.resource_id) AS assigned_asset_count ',
'FROM user_info u ',
' LEFT JOIN group_info g ON u.group_id = g.group_id ',
' LEFT JOIN resource_info r ON u.user_id = r.user_id ',
v_where_clause,
'GROUP BY u.user_id, u.user_name, u.email_address, g.group_name ',
v_order_by_clause,
' LIMIT ? OFFSET ?'
);
PREPARE stmt FROM v_sql;
IF p_group_id IS NOT NULL THEN
EXECUTE stmt USING p_group_id, p_page_size, v_offset;
ELSE
EXECUTE stmt USING p_page_size, v_offset;
END IF;
SELECT FOUND_ROWS() AS total_count;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;

View File

@ -0,0 +1,43 @@
DELIMITER $$
CREATE PROCEDURE `sp_search_users_for_autocomplete_paged`(
IN p_search_term VARCHAR(255),
IN p_page_num INT,
IN p_page_size INT,
IN p_total_count_limit INT -- FOUND_ROWS() 계산 시 과도한 스캔 방지용 (선택적)
)
BEGIN
DECLARE v_offset INT;
IF p_page_num IS NULL OR p_page_num < 1 THEN SET p_page_num = 1; END IF;
IF p_page_size IS NULL OR p_page_size < 1 THEN SET p_page_size = 10; END IF;
SET v_offset = (p_page_num - 1) * p_page_size;
-- 실제 데이터 조회 (페이지네이션 적용)
SELECT SQL_CALC_FOUND_ROWS DISTINCT -- DISTINCT 유지, SQL_CALC_FOUND_ROWS 추가
user_id,
CASE
WHEN display_name IS NOT NULL AND display_name != '' AND account_name IS NOT NULL THEN CONCAT(display_name, ' [', account_name, ']')
WHEN display_name IS NOT NULL AND display_name != '' THEN display_name
ELSE account_name
END AS user_display_name
FROM user_info
WHERE
(p_search_term IS NULL OR p_search_term = '' OR
LOWER(display_name) LIKE CONCAT('%', LOWER(p_search_term), '%') OR
LOWER(account_name) LIKE CONCAT('%', LOWER(p_search_term), '%'))
ORDER BY user_display_name
LIMIT v_offset, p_page_size; -- OFFSET, LIMIT 순서 주의
-- 전체 결과 수 조회 (LIMIT 절에 의해 영향받지 않음)
-- p_total_count_limit 값은 이 SELECT 문의 LIMIT 과는 별개로,
-- FOUND_ROWS()가 너무 큰 테이블 전체를 스캔하는 것을 방지하기 위한 최적화 기법으로 사용될 수 있으나,
-- MySQL/MariaDB 에서 FOUND_ROWS()는 이전 SELECT 문의 LIMIT을 무시하고 실제 필터링된 전체 행 수를 계산합니다.
-- 따라서 p_total_count_limit 파라미터는 여기서는 직접적인 용도가 없을 수 있습니다.
-- 만약 필요하다면, 별도의 COUNT(*) 쿼리를 조건부로 실행하는 등의 로직을 추가할 수 있습니다.
SELECT FOUND_ROWS() AS total_count;
END
$$
DELIMITER ;

View File

@ -0,0 +1,131 @@
DELIMITER $$
CREATE PROCEDURE `sp_sync_resource_info_from_scan`( -- 새 이름으로 생성
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_user_account_name VARCHAR(255), -- 사용자 계정명
IN p_category VARCHAR(100), -- 스캔된 카테고리명
IN p_manufacturer VARCHAR(100), -- 스캔된 제조사
IN p_resource_name VARCHAR(100), -- 스캔된 제품명
IN p_serial_num VARCHAR(200), -- 스캔된 시리얼 번호
IN p_spec_value VARCHAR(255), -- 스캔된 사양 값 (문자열)
IN p_spec_unit VARCHAR(10), -- 스캔된 사양 단위 (문자열)
IN p_detected_by VARCHAR(50), -- 스캔 도구 정보 등 (현재 로직 미사용)
IN p_change_type TINYINT, -- 1: ADD(추가/할당), 2: DELETE(할당 해제)
OUT p_result_message VARCHAR(255)
)
COMMENT '스캔 정보 기반 자산 정보 동기화(추가/할당/해제) 및 로그 (Rust 연동용)'
BEGIN
DECLARE v_user_id BIGINT DEFAULT NULL;
DECLARE v_category_id TINYINT UNSIGNED;
DECLARE v_spec_unit_id TINYINT UNSIGNED DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE v_existing_resource_id BIGINT;
DECLARE v_common_log VARCHAR(255);
DECLARE v_new_spec_value DECIMAL(10, 2) DEFAULT NULL;
DECLARE v_comments_to_set VARCHAR(200) DEFAULT NULL;
DECLARE v_existing_user_id BIGINT; -- 기존 자산의 할당 사용자 ID
DECLARE v_is_locked BOOLEAN DEFAULT FALSE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO, @sqlstate = RETURNED_SQLSTATE, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('처리 중 오류 발생 (', @errno, '/', @sqlstate, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보(관리자 ID 또는 프로세스 설명)는 필수입니다.';
ELSE
-- 트랜잭션 시작
START TRANSACTION;
SET p_result_message = NULL;
-- 카테고리/단위 ID 매핑
IF p_category = 'VGA' THEN
SET p_category = 'GPU';
END IF;
SELECT category_id INTO v_category_id FROM resource_category WHERE category_name = p_category LIMIT 1;
IF v_category_id IS NULL THEN
SET v_category_id = 0; -- 기본값 0 또는 다른 처리
SET p_result_message = CONCAT('주의: 알 수 없는 카테고리(', p_category, ')가 ID 0으로 처리됨. ');
END IF;
SET v_spec_unit_id = CASE LOWER(TRIM(p_spec_unit)) WHEN 'mhz' THEN 1 WHEN 'mb' THEN 2 WHEN 'gb' THEN 3 WHEN 'tb' THEN 4 WHEN 'pb' THEN 5 WHEN 'inch' THEN 6 ELSE NULL END;
-- 사용자 ID 조회
SELECT user_id INTO v_user_id FROM user_info WHERE LOWER(account_name) = LOWER(p_user_account_name) LIMIT 1;
SET v_common_log = CONCAT(p_user_account_name, ' - ', p_category, ' (SN:', IFNULL(p_serial_num, 'N/A'), ')');
-- 스펙 값 처리
IF p_change_type = 1 AND p_spec_value IS NOT NULL AND p_spec_value != 'N/A' THEN
IF p_spec_value REGEXP '^[0-9]+([.][0-9]+)?$' THEN SET v_new_spec_value = CAST(p_spec_value AS DECIMAL(10, 2));
ELSE SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '주의: Spec 값 "', p_spec_value, '"는 유효 숫자가 아님. '); END IF;
END IF;
-- === 변경 타입 분기 ===
IF p_change_type = 1 THEN -- ADD (자산 추가 또는 사용자 할당)
IF p_serial_num IS NULL OR p_serial_num = '' THEN
ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '추가/할당 실패: 시리얼 번호는 필수입니다. ', v_common_log);
ELSE
-- 시리얼 번호로 기존 자산 조회
SELECT resource_id, user_id INTO v_existing_resource_id, v_existing_user_id FROM resource_info WHERE serial_num = p_serial_num LIMIT 1;
IF v_existing_resource_id IS NOT NULL THEN -- 자산 존재
IF v_is_locked = TRUE THEN -- ★★★ 자산이 잠겨있는 경우 ★★★
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '자산이 잠겨있어 스캔 정보로 업데이트하지 않음: ', v_common_log);
ELSE
IF v_existing_user_id IS NULL AND v_user_id IS NOT NULL THEN -- 미할당 자산 -> 사용자 할당
UPDATE resource_info SET user_id = v_user_id, update_date = v_now WHERE resource_id = v_existing_resource_id;
INSERT INTO log_update_resource (log_date, admin_user_id, actor_description, resource_id, user_id) VALUES (v_now, p_admin_user_id, p_actor_description, v_existing_resource_id, v_user_id);
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '기존 미할당 자산에 사용자 할당 완료: ', v_common_log);
COMMIT;
ELSEIF v_existing_user_id = v_user_id THEN -- 이미 해당 사용자에게 할당됨
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '이미 사용자에게 할당된 동일 자산: ', v_common_log); COMMIT;
ELSE -- 다른 사용자 할당 or 중복 추가 시도
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '이미 등록된 시리얼 번호 (다른 사용자 또는 중복): ', v_common_log); COMMIT;
END IF;
END IF;
ELSE -- 자산 미존재 (신규 추가)
IF v_category_id = 0 THEN -- 유효하지 않은 카테고리 (선택적)
ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '추가 실패: 유효한 카테고리 정보가 필요합니다.');
ELSE
IF v_user_id IS NULL THEN SET v_comments_to_set = CONCAT('Detected from Host: ', p_user_account_name); END IF;
INSERT INTO resource_info (category_id, manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments, register_date, is_locked) VALUES (v_category_id, p_manufacturer, p_resource_name, p_serial_num, v_new_spec_value, v_spec_unit_id, v_user_id, v_comments_to_set, v_now, FALSE);
SET v_existing_resource_id = LAST_INSERT_ID();
INSERT INTO log_add_resource (log_date, admin_user_id, actor_description, resource_id, category_id, resource_code, manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments, purchase_date, register_date) SELECT v_now, p_admin_user_id, p_actor_description, r.resource_id, r.category_id, r.resource_code, r.manufacturer, r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, r.comments, r.purchase_date, r.register_date FROM resource_info r WHERE r.resource_id = v_existing_resource_id;
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '신규 등록 완료: ', v_common_log);
COMMIT;
END IF; -- 카테고리 유효성 IF 종료
END IF; -- 자산 존재 IF 종료
END IF; -- 시리얼 번호 유효성 IF 종료
ELSEIF p_change_type = 2 THEN -- DELETE (사용자 할당 해제)
IF v_user_id IS NULL THEN
ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '할당 해제 실패: 기준 사용자 ID를 찾을 수 없습니다. (', p_user_account_name, ')');
ELSEIF p_serial_num IS NULL OR p_serial_num = '' THEN
ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '할당 해제 실패: 기준 시리얼 번호가 없습니다. ', v_common_log);
ELSE
SELECT resource_id, is_locked INTO v_existing_resource_id, v_is_locked FROM resource_info WHERE user_id = v_user_id AND serial_num = p_serial_num LIMIT 1;
IF v_existing_resource_id IS NULL THEN
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '할당 해제 대상 없음 (사용자 + 시리얼 기준). ', v_common_log); COMMIT;
ELSEIF v_is_locked = TRUE THEN
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '자산이 잠겨있어 자동 할당 해제하지 않음: ', v_common_log); COMMIT;
ELSE
UPDATE resource_info SET user_id = NULL, update_date = v_now WHERE resource_id = v_existing_resource_id;
INSERT INTO log_update_resource (log_date, admin_user_id, actor_description, resource_id, user_id) VALUES (v_now, p_admin_user_id, p_actor_description, v_existing_resource_id, NULL);
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '사용자 할당 해제 완료: ', v_common_log);
COMMIT;
END IF; -- 할당 해제 대상 존재 IF 종료
END IF; -- 파라미터 유효성 IF 종료
ELSE -- 알 수 없는 타입
SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '알 수 없는 작업 타입: ', p_change_type); COMMIT;
END IF; -- 변경 타입 IF 종료
END IF; -- 작업 주체 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,56 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_update_category_name`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_category_id TINYINT UNSIGNED,
IN p_new_category_name VARCHAR(40),
OUT p_result_message VARCHAR(255)
)
COMMENT '카테고리 이름 수정 및 로그 기록'
BEGIN
DECLARE v_old_category_name VARCHAR(40);
DECLARE v_existing_cat_id TINYINT UNSIGNED DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSEIF p_new_category_name IS NULL OR p_new_category_name = '' THEN
SET p_result_message = '카테고리 이름은 필수입니다.';
ELSE
-- 기존 정보 조회 및 존재 확인
SELECT category_name INTO v_old_category_name FROM resource_category WHERE category_id = p_category_id;
IF v_old_category_name IS NULL THEN
SET p_result_message = CONCAT('수정할 카테고리를 찾을 수 없습니다 (ID: ', p_category_id, ')');
ELSE
-- 카테고리 이름 중복 검사 (자기 자신 제외)
SELECT category_id INTO v_existing_cat_id FROM resource_category WHERE LOWER(category_name) = LOWER(p_new_category_name) AND category_id != p_category_id LIMIT 1;
IF v_existing_cat_id IS NOT NULL THEN
SET p_result_message = CONCAT('이미 사용 중인 카테고리 이름입니다: ', p_new_category_name);
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
UPDATE resource_category SET category_name = p_new_category_name WHERE category_id = p_category_id;
INSERT INTO log_update_category (log_date, admin_user_id, actor_description, category_id, old_category_name, new_category_name)
VALUES (v_now, p_admin_user_id, p_actor_description, p_category_id, v_old_category_name, p_new_category_name);
COMMIT;
SET p_result_message = CONCAT('카테고리 (ID: ', p_category_id, ') 이름 수정 완료.');
END IF; -- 이름 중복 IF 종료
END IF; -- 카테고리 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,68 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_update_group`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_group_id BIGINT,
IN p_group_name VARCHAR(100),
IN p_manager_user_id BIGINT, -- 파라미터명 변경됨
OUT p_result_message VARCHAR(255)
)
COMMENT '그룹(부서) 정보 수정 및 로그 기록'
BEGIN
DECLARE v_old_group_name VARCHAR(100);
DECLARE v_old_manager_user_id BIGINT; -- 변수명 변경됨
DECLARE v_existing_group_id BIGINT DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
ELSEIF p_group_name IS NULL OR p_group_name = '' THEN
SET p_result_message = '그룹(부서) 이름은 필수입니다.';
ELSE
-- 기존 정보 조회 및 존재 확인
SELECT group_name, manager_user_id INTO v_old_group_name, v_old_manager_user_id -- 컬럼명/변수명 변경
FROM group_info WHERE group_id = p_group_id;
IF v_old_group_name IS NULL THEN
SET p_result_message = CONCAT('수정할 그룹(부서)을 찾을 수 없습니다 (ID: ', p_group_id, ')');
ELSE
-- 그룹 이름 중복 검사 (자기 자신 제외)
SELECT group_id INTO v_existing_group_id
FROM group_info WHERE LOWER(group_name) = LOWER(p_group_name) AND group_id != p_group_id LIMIT 1;
IF v_existing_group_id IS NOT NULL THEN
SET p_result_message = CONCAT('이미 다른 그룹(부서)에서 사용 중인 이름입니다: ', p_group_name);
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
UPDATE group_info SET
group_name = p_group_name,
manager_user_id = p_manager_user_id -- 컬럼명/파라미터명 변경
WHERE group_id = p_group_id;
INSERT INTO log_update_group (log_date, admin_user_id, actor_description, group_id,
old_group_name, old_manager_user_id, -- 컬럼명 변경
new_group_name, new_manager_user_id) -- 컬럼명 변경
VALUES (v_now, p_admin_user_id, p_actor_description, p_group_id,
v_old_group_name, v_old_manager_user_id, -- 변수명 변경
p_group_name, p_manager_user_id); -- 파라미터명 변경
COMMIT;
SET p_result_message = CONCAT('그룹(부서) (ID: ', p_group_id, ') 정보 수정 완료.');
END IF; -- 그룹 이름 중복 IF 종료
END IF; -- 그룹 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;

View File

@ -0,0 +1,67 @@
DELIMITER $$
CREATE PROCEDURE `sp_update_resource`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_resource_id BIGINT,
IN p_category_id TINYINT UNSIGNED,
IN p_resource_code VARCHAR(100),
IN p_manufacturer VARCHAR(100),
IN p_resource_name VARCHAR(100),
IN p_serial_num VARCHAR(200),
IN p_spec_value DECIMAL(10, 2),
IN p_spec_unit TINYINT UNSIGNED,
IN p_user_id BIGINT,
IN p_comments VARCHAR(200),
IN p_purchase_date DATE,
IN p_is_locked BOOLEAN
)
COMMENT '자산 정보 수정 및 로그 기록'
BEGIN
-- DECLARE v_original_create_date DATETIME; -- register_date로 대체
DECLARE v_now DATETIME DEFAULT NOW();
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '작업 주체 정보(관리자 ID 또는 프로세스 설명)는 필수입니다.';
END IF;
IF p_resource_name IS NULL OR p_resource_name = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '제품명은 필수입니다.';
END IF;
IF p_serial_num IS NOT NULL AND p_serial_num != '' AND EXISTS (SELECT 1 FROM resource_info WHERE serial_num = p_serial_num AND resource_id != p_resource_id) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '이미 다른 자산에서 사용 중인 시리얼 번호입니다.';
END IF;
-- 트랜잭션 시작
START TRANSACTION;
-- 자산 정보 업데이트 (update_date는 자동 업데이트)
UPDATE resource_info SET
category_id = p_category_id,
resource_code = p_resource_code,
manufacturer = p_manufacturer,
resource_name = p_resource_name,
serial_num = p_serial_num,
spec_value = p_spec_value,
spec_unit = p_spec_unit,
user_id = p_user_id,
comments = p_comments,
purchase_date = p_purchase_date,
is_locked = p_is_locked
-- register_date는 수정하지 않음
WHERE resource_id = p_resource_id;
-- 로그 기록 (변경 후 정보만 기록)
INSERT INTO log_update_resource (
log_date, admin_user_id, actor_description, resource_id, category_id, resource_code,
manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments,
purchase_date -- 컬럼명 변경 반영
) VALUES (
v_now, p_admin_user_id, p_actor_description, p_resource_id, p_category_id, p_resource_code,
p_manufacturer, p_resource_name, p_serial_num, p_spec_value, p_spec_unit, p_user_id, p_comments,
p_purchase_date -- 컬럼명 변경 반영
);
COMMIT;
END
$$
DELIMITER ;

View File

@ -0,0 +1,75 @@
DELIMITER $$
SET @saved_sql_mode = @@sql_mode
$$
SET @@sql_mode = 'NO_AUTO_VALUE_ON_ZERO'
$$
CREATE PROCEDURE `sp_update_user`(
IN p_admin_user_id INT,
IN p_actor_description VARCHAR(100),
IN p_user_id BIGINT,
IN p_display_name VARCHAR(100), -- 파라미터명 변경
IN p_account_name VARCHAR(255), -- 파라미터명 변경
IN p_group_id BIGINT,
OUT p_result_message VARCHAR(255)
)
COMMENT '사용자 정보 수정 및 로그 기록'
BEGIN
DECLARE v_old_display_name VARCHAR(100);
DECLARE v_old_account_name VARCHAR(255);
DECLARE v_old_group_id BIGINT;
DECLARE v_existing_user_id BIGINT DEFAULT NULL;
DECLARE v_now DATETIME DEFAULT NOW();
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
ROLLBACK; SET p_result_message = CONCAT('DB 오류 (', @errno, '): ', @text);
END;
-- 입력값 검증
IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
SET p_result_message = '작업 주체 정보는 필수입니다.';
-- RETURN; -- ★ 제거
ELSEIF p_account_name IS NULL OR p_account_name = '' THEN
SET p_result_message = '계정 이름은 필수입니다.';
-- RETURN; -- ★ 제거
ELSE
-- 기존 정보 조회 및 존재 확인
SELECT display_name, account_name, group_id INTO v_old_display_name, v_old_account_name, v_old_group_id
FROM user_info WHERE user_id = p_user_id;
IF v_old_account_name IS NULL THEN
SET p_result_message = CONCAT('수정할 사용자를 찾을 수 없습니다 (ID: ', p_user_id, ')');
-- RETURN; -- ★ 제거
ELSE
-- 계정 이름 중복 검사 (자기 자신 제외)
SELECT user_id INTO v_existing_user_id
FROM user_info WHERE LOWER(account_name) = LOWER(p_account_name) AND user_id != p_user_id LIMIT 1;
IF v_existing_user_id IS NOT NULL THEN
SET p_result_message = CONCAT('이미 다른 사용자가 사용 중인 계정 이름입니다: ', p_account_name);
-- RETURN; -- ★ 제거
ELSE
-- 모든 검증 통과, 트랜잭션 시작
START TRANSACTION;
UPDATE user_info SET
display_name = p_display_name,
account_name = p_account_name,
group_id = p_group_id
WHERE user_id = p_user_id;
INSERT INTO log_update_user (log_date, admin_user_id, actor_description, user_id,
old_display_name, old_account_name, old_group_id,
new_display_name, new_account_name, new_group_id)
VALUES (v_now, p_admin_user_id, p_actor_description, p_user_id,
v_old_display_name, v_old_account_name, v_old_group_id,
p_display_name, p_account_name, p_group_id);
COMMIT;
SET p_result_message = CONCAT('사용자 (ID: ', p_user_id, ') 정보 수정 완료.');
END IF; -- 계정 중복 IF 종료
END IF; -- 사용자 존재 IF 종료
END IF; -- 입력값 검증 IF 종료
END
$$
DELIMITER ;