From 6ef8463c4e1b27f54c62411fbb48d94184d80e7f Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:03:35 +0900 Subject: [PATCH 01/25] Function enhancement - Support for multiple DB brands - Creating a multilingual message and global time zone definition object --- config/dbinfo.json | 29 ++++- package-lock.json | 100 ++++++++++++++- package.json | 12 +- src/database/DatabaseFactory.js | 85 +++++++++++++ src/database/MSSQLAdapter.js | 187 +++++++++++++++++++++++++++ src/database/MySQLAdapter.js | 218 ++++++++++++++++++++++++++++++++ src/excel-cli.js | 32 ++--- src/index.js | 41 ++++-- src/utils/date-utils.js | 129 +++++++++++++++++++ src/utils/messages.js | 165 ++++++++++++++++++++++++ src/variable-processor.js | 61 ++++----- 11 files changed, 980 insertions(+), 79 deletions(-) create mode 100644 src/database/DatabaseFactory.js create mode 100644 src/database/MSSQLAdapter.js create mode 100644 src/database/MySQLAdapter.js create mode 100644 src/utils/date-utils.js create mode 100644 src/utils/messages.js diff --git a/config/dbinfo.json b/config/dbinfo.json index cb5b822..9506c8d 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -1,5 +1,6 @@ { "sampleDB": { + "type": "mssql", "user": "sample", "password": "sample1234!", "server": "localhost", @@ -8,14 +9,38 @@ "options": { "encrypt": true, "trustServerCertificate": true } }, "erpDB": { - "user": "erp", - "password": "erp1234!", + "type": "mssql", + "user": "sample", + "password": "sample1234!", "server": "localhost", "database": "ERP_DB", "port": 1433, "options": { "encrypt": true, "trustServerCertificate": true } }, + "mysql": { + "type": "mysql", + "user": "sahara", + "password": "1111", + "server": "localhost", + "database": "etcdb", + "port": 3306, + "options": { + "connectionTimeout": 30000 + } + }, + "mariaDB": { + "type": "mariadb", + "user": "sahara", + "password": "1111", + "server": "localhost", + "database": "mydb", + "port": 3306, + "options": { + "connectionTimeout": 30000 + } + }, "sourceDB": { + "type": "mssql", "user": "sample", "password": "sample1234!", "server": "localhost", diff --git a/package-lock.json b/package-lock.json index a61ae5d..d064a74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,22 @@ { "name": "sql2excel", - "version": "1.2.5", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql2excel", - "version": "1.2.5", + "version": "1.3.0", "dependencies": { "exceljs": "^4.3.0", "json5": "^2.2.3", "mssql": "^10.0.0", + "mysql2": "^3.4.0", "xml2js": "^0.6.2", "yargs": "^17.7.2" }, "bin": { - "sql2excel": "src/excel-cli.js" + "sql2excel": "app.js" }, "devDependencies": { "pkg": "^5.8.1" @@ -1270,6 +1271,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -1786,6 +1796,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2427,6 +2446,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -2915,6 +2940,21 @@ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3052,6 +3092,46 @@ "readable-stream": "^3.6.0" } }, + "node_modules/mysql2": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.4.0.tgz", + "integrity": "sha512-l952dVcdWVfEIIxMQ1PNSPHYY2htylG7H9ahrQe9lIgDpEMg3hB0S88OhC/loNSZpV8OcywSjgOzjSjEUiuwiQ==", + "license": "MIT", + "dependencies": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "license": "ISC", + "engines": { + "node": ">=16.14" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "license": "MIT", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", @@ -3778,6 +3858,11 @@ "node": ">=10" } }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -3965,6 +4050,15 @@ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "license": "BSD-3-Clause" }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", diff --git a/package.json b/package.json index d41090c..53ce728 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "1.2.9", + "version": "1.3.0", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { @@ -28,7 +28,8 @@ "templates/**/*.xml", ".env", "node_modules/mssql/**/*", - "node_modules/tedious/**/*" + "node_modules/tedious/**/*", + "node_modules/mysql2/**/*" ], "targets": [ "node18-win-x64" @@ -36,11 +37,12 @@ "outputPath": "dist" }, "dependencies": { - "mssql": "^10.0.0", "exceljs": "^4.3.0", "json5": "^2.2.3", - "yargs": "^17.7.2", - "xml2js": "^0.6.2" + "mssql": "^10.0.0", + "mysql2": "^3.4.0", + "xml2js": "^0.6.2", + "yargs": "^17.7.2" }, "devDependencies": { "pkg": "^5.8.1" diff --git a/src/database/DatabaseFactory.js b/src/database/DatabaseFactory.js new file mode 100644 index 0000000..264894c --- /dev/null +++ b/src/database/DatabaseFactory.js @@ -0,0 +1,85 @@ +const MSSQLAdapter = require('./MSSQLAdapter'); +const MySQLAdapter = require('./MySQLAdapter'); +const { getMessages } = require('../utils/messages'); + +/** + * DatabaseFactory - 데이터베이스 타입에 따라 적절한 어댑터를 생성 + */ +class DatabaseFactory { + /** + * 데이터베이스 연결 어댑터 생성 + * @param {string} dbType - 데이터베이스 타입 (mssql, mysql, mariadb) + * @param {Object} config - 데이터베이스 연결 설정 + * @param {string} language - 언어 설정 (en/kr) + * @returns {Object} 데이터베이스 어댑터 인스턴스 + */ + static createAdapter(dbType, config, language = 'en') { + const msg = getMessages('database', language); + const normalizedType = (dbType || 'mssql').toLowerCase(); + + switch (normalizedType) { + case 'mssql': + case 'sqlserver': + return new MSSQLAdapter(config, language); + + case 'mysql': + case 'mariadb': + return new MySQLAdapter(config, language); + + default: + throw new Error(`${msg.unsupportedDbType} ${dbType}`); + } + } + + /** + * 지원하는 데이터베이스 타입 목록 + * @returns {Array} 지원 DB 타입 정보 + */ + static getSupportedTypes() { + return [ + { type: 'mssql', name: 'Microsoft SQL Server', defaultPort: 1433 }, + { type: 'mysql', name: 'MySQL', defaultPort: 3306 }, + { type: 'mariadb', name: 'MariaDB', defaultPort: 3306 } + ]; + } + + /** + * 데이터베이스 타입별 기본 포트 번호 + * @param {string} dbType - 데이터베이스 타입 + * @returns {number|null} 기본 포트 번호 + */ + static getDefaultPort(dbType) { + const typeInfo = this.getSupportedTypes().find(t => t.type === dbType.toLowerCase()); + return typeInfo ? typeInfo.defaultPort : null; + } + + /** + * 데이터베이스 설정 유효성 검증 + * @param {string} dbType - 데이터베이스 타입 + * @param {Object} config - 데이터베이스 설정 + * @param {string} language - 언어 설정 + * @returns {boolean} 유효성 검증 결과 + */ + static validateConfig(dbType, config, language = 'en') { + const msg = getMessages('database', language); + const requiredFields = ['server', 'database', 'user', 'password']; + const missingFields = requiredFields.filter(field => !config[field]); + + if (missingFields.length > 0) { + throw new Error(`${msg.requiredConfigMissing} ${missingFields.join(', ')}`); + } + + // Port number validation (optional, use default if not provided) + if (config.port) { + const port = parseInt(config.port, 10); + if (isNaN(port) || port < 1 || port > 65535) { + throw new Error(msg.portInvalid); + } + } + + return true; + } +} + +module.exports = DatabaseFactory; + diff --git a/src/database/MSSQLAdapter.js b/src/database/MSSQLAdapter.js new file mode 100644 index 0000000..6d6c1d6 --- /dev/null +++ b/src/database/MSSQLAdapter.js @@ -0,0 +1,187 @@ +const mssql = require('mssql'); +const { getMessages } = require('../utils/messages'); +const { formatDate, createInClause } = require('../utils/date-utils'); + +/** + * MSSQL 데이터베이스 어댑터 + */ +class MSSQLAdapter { + constructor(config, language = 'en') { + this.config = config; + this.msg = getMessages('database', language); + this.dbPools = {}; + this.dbType = 'mssql'; + } + + /** + * MSSQL 연결 풀 생성 + * @param {Object} config - MSSQL 연결 설정 + * @param {string} dbKey - 데이터베이스 키 + * @returns {Promise} 연결 풀 + */ + async createConnectionPool(config, dbKey) { + if (!this.dbPools[dbKey]) { + if (!config) { + throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); + } + + console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); + const pool = new mssql.ConnectionPool(config); + await pool.connect(); + this.dbPools[dbKey] = pool; + console.log(`[DB] ${dbKey} ${this.msg.dbConnected}`); + } + return this.dbPools[dbKey]; + } + + /** + * MSSQL 쿼리 실행 + * @param {mssql.ConnectionPool} pool - 연결 풀 + * @param {string} sql - SQL 쿼리 + * @returns {Promise} 쿼리 결과 + */ + async executeQuery(pool, sql) { + return await pool.request().query(sql); + } + + /** + * MSSQL TOP 절 추가 (MSSQL 특화) + * @param {string} sql - 원본 SQL 쿼리 + * @param {number} maxRows - 최대 행 수 + * @returns {string} TOP 절이 추가된 SQL + */ + addTopClause(sql, maxRows) { + if (!maxRows || maxRows <= 0) return sql; + + // SQL에 TOP 절이 없는 경우에만 추가 + if (!sql.trim().toUpperCase().includes('TOP ')) { + // SELECT 다음에 TOP N을 삽입 + return sql.replace(/^\s*SELECT\s+/i, `SELECT TOP ${maxRows} `); + } + return sql; + } + + /** + * MSSQL GETDATE() 함수 대체 (MSSQL 특화) + * @param {string} sql - SQL 쿼리 + * @returns {string} GETDATE() 함수가 치환된 SQL + */ + replaceGetDateFunction(sql) { + // MSSQL의 GETDATE() 함수를 JavaScript Date로 치환 + const currentDate = new Date().toISOString().slice(0, 19).replace('T', ' '); + return sql.replace(/\bGETDATE\(\)\b/gi, `'${currentDate}'`); + } + + /** + * 날짜 포맷팅 함수 (재사용 가능한 유틸리티 함수 사용) + * @param {Date} date - Date 객체 + * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) + * @returns {string} 포맷팅된 날짜 문자열 + */ + formatDate(date, format) { + return formatDate(date, format); + } + + /** + * MSSQL IN 절 생성 (재사용 가능한 유틸리티 함수 사용) + * @param {Array} values - 값 배열 + * @returns {string} IN 절 문자열 + */ + createInClause(values) { + return createInClause(values); + } + + /** + * MSSQL 연결 설정 검증 + * @param {Object} config - 연결 설정 + * @returns {boolean} 유효성 여부 + */ + validateConnectionConfig(config) { + const requiredFields = ['server', 'database', 'user', 'password']; + return requiredFields.every(field => config.hasOwnProperty(field)); + } + + /** + * MSSQL 연결 풀 종료 + * @param {string} dbKey - 데이터베이스 키 + */ + async closeConnection(dbKey) { + if (this.dbPools[dbKey]) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + await this.dbPools[dbKey].close(); + delete this.dbPools[dbKey]; + } + } + + /** + * 모든 MSSQL 연결 풀 종료 + */ + async closeAllConnections() { + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + await pool.close(); + } + this.dbPools = {}; + } + + /** + * MSSQL 특화 에러 처리 + * @param {Error} error - 에러 객체 + * @returns {string} 사용자 친화적인 에러 메시지 + */ + formatErrorMessage(error) { + if (error.code === 'ELOGIN') { + return this.msg.errorLogin; + } else if (error.code === 'ESOCKET') { + return this.msg.errorSocket; + } else if (error.code === 'ENAME') { + return this.msg.errorName; + } else if (error.code === 'ETIMEOUT') { + return this.msg.errorTimeout; + } else if (error.code === 'EALREADYCONNECTED') { + return this.msg.errorAlreadyConnected; + } else if (error.code === 'ENOTOPEN') { + return this.msg.errorNotOpen; + } else { + return `${this.msg.mssqlError} ${error.message}`; + } + } + + /** + * MSSQL 연결 상태 확인 + * @param {string} dbKey - 데이터베이스 키 + * @returns {boolean} 연결 상태 + */ + isConnected(dbKey) { + return this.dbPools[dbKey] && this.dbPools[dbKey].connected; + } + + /** + * MSSQL 연결 풀 정보 조회 + * @returns {Object} 연결 풀 정보 + */ + getConnectionInfo() { + const info = {}; + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + info[dbKey] = { + connected: pool.connected, + size: pool.size, + available: pool.available, + pending: pool.pending, + borrowed: pool.borrowed + }; + } + return info; + } + + /** + * 데이터베이스 타입 반환 + * @returns {string} 데이터베이스 타입 + */ + getType() { + return this.dbType; + } +} + +module.exports = MSSQLAdapter; + diff --git a/src/database/MySQLAdapter.js b/src/database/MySQLAdapter.js new file mode 100644 index 0000000..67e1ee5 --- /dev/null +++ b/src/database/MySQLAdapter.js @@ -0,0 +1,218 @@ +const mysql = require('mysql2/promise'); +const { getMessages } = require('../utils/messages'); +const { formatDate, createInClause } = require('../utils/date-utils'); + +/** + * MySQL/MariaDB 데이터베이스 어댑터 + */ +class MySQLAdapter { + constructor(config, language = 'en') { + this.config = config; + this.msg = getMessages('database', language); + this.dbPools = {}; + this.dbType = 'mysql'; + } + + /** + * MySQL 연결 생성 (Pool 대신 단일 Connection 사용) + * @param {Object} config - MySQL 연결 설정 + * @param {string} dbKey - 데이터베이스 키 + * @returns {Promise} 연결 객체 + */ + async createConnectionPool(config, dbKey) { + if (!this.dbPools[dbKey]) { + if (!config) { + throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); + } + + console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); + + const connectionConfig = { + host: config.server, + port: parseInt(config.port, 10) || 3306, + user: config.user, + password: config.password, + database: config.database, + connectTimeout: config.options?.connectionTimeout || 30000, + ssl: config.options?.ssl || false + }; + + // Pool 대신 단일 Connection 사용 (client-util-app과 동일) + const connection = await mysql.createConnection(connectionConfig); + + this.dbPools[dbKey] = connection; + console.log(`[DB] ${dbKey} ${this.msg.dbConnected}`); + } + return this.dbPools[dbKey]; + } + + /** + * MySQL 쿼리 실행 + * @param {mysql.Connection} connection - 연결 객체 + * @param {string} sql - SQL 쿼리 + * @returns {Promise} 쿼리 결과 (MSSQL 형식과 호환) + */ + async executeQuery(connection, sql) { + try { + const [rows] = await connection.execute(sql); + + // MSSQL 결과 형식과 호환되도록 변환 + return { + recordset: rows, + recordsets: [rows], + rowsAffected: [rows.affectedRows || rows.length], + output: {}, + rowCount: Array.isArray(rows) ? rows.length : 0 + }; + } catch (error) { + // 연결 에러 시 재연결 시도 + if (error.code === 'PROTOCOL_CONNECTION_LOST' || error.code === 'ECONNRESET') { + // 재연결은 createConnectionPool을 통해 자동으로 처리됨 + throw new Error(`${this.msg.errorConnection} - ${error.message}`); + } + throw error; + } + } + + /** + * MySQL LIMIT 절 추가 (MySQL 특화) + * @param {string} sql - 원본 SQL 쿼리 + * @param {number} maxRows - 최대 행 수 + * @returns {string} LIMIT 절이 추가된 SQL + */ + addTopClause(sql, maxRows) { + if (!maxRows || maxRows <= 0) return sql; + + // SQL에 LIMIT 절이 없는 경우에만 추가 + const upperSql = sql.trim().toUpperCase(); + if (!upperSql.includes('LIMIT ')) { + // SQL 끝에 LIMIT N 추가 + return `${sql.trim()} LIMIT ${maxRows}`; + } + return sql; + } + + /** + * MySQL NOW() 함수 대체 (MySQL 특화) + * @param {string} sql - SQL 쿼리 + * @returns {string} NOW() 함수가 치환된 SQL + */ + replaceGetDateFunction(sql) { + // MySQL은 NOW() 함수를 지원하므로, GETDATE()를 NOW()로 변경 + return sql.replace(/\bGETDATE\(\)\b/gi, 'NOW()'); + } + + /** + * 날짜 포맷팅 함수 (재사용 가능한 유틸리티 함수 사용) + * @param {Date} date - Date 객체 + * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) + * @returns {string} 포맷팅된 날짜 문자열 + */ + formatDate(date, format) { + return formatDate(date, format); + } + + /** + * MySQL IN 절 생성 (재사용 가능한 유틸리티 함수 사용) + * @param {Array} values - 값 배열 + * @returns {string} IN 절 문자열 + */ + createInClause(values) { + return createInClause(values); + } + + /** + * MySQL 연결 설정 검증 + * @param {Object} config - 연결 설정 + * @returns {boolean} 유효성 여부 + */ + validateConnectionConfig(config) { + const requiredFields = ['server', 'database', 'user', 'password']; + return requiredFields.every(field => config.hasOwnProperty(field)); + } + + /** + * MySQL 연결 종료 + * @param {string} dbKey - 데이터베이스 키 + */ + async closeConnection(dbKey) { + if (this.dbPools[dbKey]) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await this.dbPools[dbKey].end(); + } catch (error) { + console.warn(`Warning: MySQL disconnect error: ${error.message}`); + } + delete this.dbPools[dbKey]; + } + } + + /** + * 모든 MySQL 연결 종료 + */ + async closeAllConnections() { + for (const [dbKey, connection] of Object.entries(this.dbPools)) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await connection.end(); + } catch (error) { + console.warn(`Warning: MySQL disconnect error: ${error.message}`); + } + } + this.dbPools = {}; + } + + /** + * MySQL 특화 에러 처리 + * @param {Error} error - 에러 객체 + * @returns {string} 사용자 친화적인 에러 메시지 + */ + formatErrorMessage(error) { + if (error.code === 'ER_ACCESS_DENIED_ERROR') { + return this.msg.errorAuth; + } else if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') { + return this.msg.errorConnection; + } else if (error.code === 'ER_BAD_DB_ERROR') { + return this.msg.errorDatabase; + } else if (error.code === 'PROTOCOL_CONNECTION_LOST') { + return this.msg.errorConnection; + } else { + return `${this.msg.mysqlError} ${error.message}`; + } + } + + /** + * MySQL 연결 상태 확인 + * @param {string} dbKey - 데이터베이스 키 + * @returns {boolean} 연결 상태 + */ + isConnected(dbKey) { + return this.dbPools[dbKey] !== undefined; + } + + /** + * MySQL 연결 정보 조회 + * @returns {Object} 연결 정보 + */ + getConnectionInfo() { + const info = {}; + for (const [dbKey, connection] of Object.entries(this.dbPools)) { + info[dbKey] = { + connected: true, + threadId: connection.threadId + }; + } + return info; + } + + /** + * 데이터베이스 타입 반환 + * @returns {string} 데이터베이스 타입 + */ + getType() { + return this.dbType; + } +} + +module.exports = MySQLAdapter; + diff --git a/src/excel-cli.js b/src/excel-cli.js index ac1c910..2ab1c40 100644 --- a/src/excel-cli.js +++ b/src/excel-cli.js @@ -352,28 +352,20 @@ function loadDatabaseConfig(configPath) { // 데이터베이스 연결 테스트 async function testDatabaseConnection(dbKey, dbConfig) { - let pool = null; + let connection = null; + let adapter = null; try { console.log(msg.dbConnecting.replace('{dbKey}', dbKey)); - pool = new mssql.ConnectionPool({ - user: dbConfig.user, - password: dbConfig.password, - server: dbConfig.server, - database: dbConfig.database, - port: dbConfig.port || 1433, - options: dbConfig.options || { - encrypt: true, - trustServerCertificate: true - }, - connectionTimeout: 10000, - requestTimeout: 5000 - }); - - await pool.connect(); + // DatabaseFactory를 사용하여 적절한 어댑터 생성 + const DatabaseFactory = require('./database/DatabaseFactory'); + const dbType = dbConfig.type || 'mssql'; + + adapter = DatabaseFactory.createAdapter(dbType, dbConfig, LANGUAGE); + connection = await adapter.createConnectionPool(dbConfig, dbKey); - const request = pool.request(); - await request.query('SELECT 1 as test'); + // 연결 테스트 쿼리 실행 + await adapter.executeQuery(connection, 'SELECT 1 as test'); console.log(msg.dbConnectionSuccess.replace('{dbKey}', dbKey)); return { success: true, message: msg.dbConnectionSuccess.replace('{dbKey}', '') }; @@ -383,9 +375,9 @@ async function testDatabaseConnection(dbKey, dbConfig) { return { success: false, message: error.message }; } finally { - if (pool) { + if (connection && adapter) { try { - await pool.close(); + await adapter.closeConnection(dbKey); } catch (closeError) { // 연결 종료 오류는 무시 } diff --git a/src/index.js b/src/index.js index cefcc31..ea62486 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ const VariableProcessor = require('./variable-processor'); const StyleManager = require('./style-manager'); const QueryParser = require('./query-parser'); const ExcelGenerator = require('./excel-generator'); -const MSSQLHelper = require('./mssql-helper'); +const DatabaseFactory = require('./database/DatabaseFactory'); // 언어 설정 (환경 변수 사용, 기본값 영어) const LANGUAGE = process.env.LANGUAGE || 'en'; @@ -217,14 +217,22 @@ async function main() { } const configObj = JSON5.parse(FileUtils.readFileSafely(configPath, 'utf8')); - // MSSQL 헬퍼 인스턴스 생성 - const mssqlHelper = new MSSQLHelper(LANGUAGE); + // DB 어댑터 맵 (각 DB별로 적절한 어댑터 생성) + const dbAdapters = {}; - // 연결 설정 검증 + // 연결 설정 검증 및 어댑터 생성 for (const [dbKey, config] of Object.entries(configObj || {})) { - if (!mssqlHelper.validateConnectionConfig(config)) { + // type이 없으면 기본값 'mssql' 사용 (하위 호환성) + const dbType = config.type || 'mssql'; + + // 어댑터 생성 + const adapter = DatabaseFactory.createAdapter(dbType, config, LANGUAGE); + + if (!adapter.validateConnectionConfig(config)) { throw new Error(`${msg.dbConfigInvalid} ${dbKey} ${msg.requiredFields}`); } + + dbAdapters[dbKey] = adapter; } // 기본 DB 연결 설정 @@ -235,15 +243,19 @@ async function main() { // DB 연결 풀 생성 함수 async function getDbPool(dbKey) { - return await mssqlHelper.createConnectionPool(configObj[dbKey], dbKey); + const adapter = dbAdapters[dbKey]; + return await adapter.createConnectionPool(configObj[dbKey], dbKey); } + // 기본 DB 어댑터 가져오기 + const defaultAdapter = dbAdapters[defaultDbKey]; + // 기본 DB 연결 const defaultPool = await getDbPool(defaultDbKey); // 동적 변수 처리 (DB 연결 후, 시트 처리 전) if (dynamicVars && dynamicVars.length > 0) { - await variableProcessor.processDynamicVariables(dynamicVars, mssqlHelper, defaultDbKey, mergedVars, configObj); + await variableProcessor.processDynamicVariables(dynamicVars, defaultAdapter, defaultDbKey, mergedVars, configObj); } // 엑셀 파일 경로 결정 (CLI > excel > 쿼리파일 > 기본값) @@ -295,9 +307,11 @@ async function main() { // maxRows 제한 적용 (개별 시트 설정 > 전역 설정 우선) const effectiveMaxRows = sheetDef.maxRows || globalMaxRows; if (effectiveMaxRows && effectiveMaxRows > 0) { - // MSSQL 헬퍼를 사용하여 TOP 절 추가 + // 시트별 DB 어댑터를 사용하여 TOP/LIMIT 절 추가 + const sheetDbKey = sheetDef.db || defaultDbKey; + const sheetAdapter = dbAdapters[sheetDbKey]; const originalSql = sql; - sql = mssqlHelper.addTopClause(sql, effectiveMaxRows); + sql = sheetAdapter.addTopClause(sql, effectiveMaxRows); if (originalSql !== sql) { const source = sheetDef.maxRows ? msg.maxRowsLimitSheet : msg.maxRowsLimitGlobal; @@ -309,11 +323,12 @@ async function main() { // 시트별 DB 연결 결정 (개별 시트 설정 > 기본 DB 설정 우선) const sheetDbKey = sheetDef.db || defaultDbKey; + const currentAdapter = dbAdapters[sheetDbKey]; const currentPool = await getDbPool(sheetDbKey); console.log(`${msg.infoExecuting} '${sheetName}' ${msg.onDb} '${sheetDbKey}'`); try { - const result = await mssqlHelper.executeQuery(currentPool, sql); + const result = await currentAdapter.executeQuery(currentPool, sql); const recordCount = result.recordset.length; // 시트별 스타일 적용 (우선순위: 시트별 > XML 전역 > CLI > 기본) @@ -371,7 +386,7 @@ async function main() { console.log(`\t---> ${recordCount} ${msg.rowsSelected} `); } catch (error) { console.log(msg.errorHeader); - console.log(mssqlHelper.formatErrorMessage(error)); + console.log(currentAdapter.formatErrorMessage(error)); console.log(`${msg.sql} ${sql}`); console.log(msg.errorFooter); } @@ -390,7 +405,9 @@ async function main() { } // 모든 DB 연결 정리 - await mssqlHelper.closeAllConnections(); + for (const adapter of Object.values(dbAdapters)) { + await adapter.closeAllConnections(); + } } // 모듈로 사용될 때를 위해 main 함수를 export diff --git a/src/utils/date-utils.js b/src/utils/date-utils.js new file mode 100644 index 0000000..9bbeec5 --- /dev/null +++ b/src/utils/date-utils.js @@ -0,0 +1,129 @@ +/** + * 날짜 관련 유틸리티 함수 모듈 + */ + +/** + * 날짜 포맷팅 함수 (UTC 기준) + * @param {Date} date - Date 객체 + * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) + * @returns {string} 포맷팅된 날짜 문자열 + * + * @example + * formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss') + * // => '2024-10-22 14:30:45' + * + * formatDate(new Date(), 'YYYY년 MM월 DD일') + * // => '2024년 10월 22일' + */ +function formatDate(date, format) { + // UTC 기준으로 날짜/시간 추출 + const map = { + 'YYYY': date.getUTCFullYear(), + 'YY': String(date.getUTCFullYear()).slice(-2), + 'MM': String(date.getUTCMonth() + 1).padStart(2, '0'), + 'M': date.getUTCMonth() + 1, + 'DD': String(date.getUTCDate()).padStart(2, '0'), + 'D': date.getUTCDate(), + 'HH': String(date.getUTCHours()).padStart(2, '0'), + 'H': date.getUTCHours(), + 'mm': String(date.getUTCMinutes()).padStart(2, '0'), + 'm': date.getUTCMinutes(), + 'ss': String(date.getUTCSeconds()).padStart(2, '0'), + 's': date.getUTCSeconds(), + 'SSS': String(date.getUTCMilliseconds()).padStart(3, '0') + }; + + let result = format; + // 긴 패턴부터 먼저 치환 (YYYY를 YY보다 먼저) + ['YYYY', 'MM', 'DD', 'HH', 'mm', 'ss', 'SSS', 'YY', 'M', 'D', 'H', 'm', 's'].forEach(token => { + result = result.replace(new RegExp(token, 'g'), map[token]); + }); + + return result; +} + +/** + * IN 절 생성 유틸리티 + * @param {Array} values - 값 배열 + * @returns {string} IN 절 문자열 + * + * @example + * createInClause([1, 2, 3]) + * // => '1, 2, 3' + * + * createInClause(['a', 'b', 'c']) + * // => "'a', 'b', 'c'" + * + * createInClause([]) + * // => 'NULL' + */ +function createInClause(values) { + if (!Array.isArray(values) || values.length === 0) { + return "NULL"; // 빈 배열일 경우 NULL 반환 (숫자/문자열 타입 모두 안전) + } + + return values.map(v => { + if (typeof v === 'string') { + return `'${v.replace(/'/g, "''")}'`; // SQL 인젝션 방지를 위한 따옴표 이스케이핑 + } + return v; + }).join(', '); +} + +/** + * 타임존별 UTC 오프셋 (분 단위) + */ +const timezoneOffsets = { + 'UTC': 0, // 협정 세계시 + 'GMT': 0, // 그리니치 표준시 (UTC와 동일) + 'KST': 540, // 한국 표준시 (UTC+9) + 'JST': 540, // 일본 표준시 (UTC+9) + 'CST': 480, // 중국 표준시 (UTC+8) + 'SGT': 480, // 싱가포르 표준시 (UTC+8) + 'PHT': 480, // 필리핀 표준시 (UTC+8) + 'AEST': 600, // 호주 동부 표준시 (UTC+10) + 'ICT': 420, // 인도차이나 표준시 (UTC+7) - 태국, 베트남 + 'CET': 60, // 중앙 유럽 표준시 (UTC+1) - 독일, 프랑스, 이탈리아, 폴란드 + 'EET': 120, // 동유럽 표준시 (UTC+2) + 'IST': 330, // 인도 표준시 (UTC+5:30) + 'GST': 240, // 걸프 표준시 (UTC+4) + 'EST': -300, // 미국 동부 표준시 (UTC-5) + 'CST_US': -360, // 미국/캐나다/멕시코 중부 표준시 (UTC-6) + 'MST': -420, // 미국 산악 표준시 (UTC-7) + 'PST': -480, // 미국 서부 표준시 (UTC-8) + 'AST': -240, // 대서양 표준시 (UTC-4) - 캐나다 동부 + 'AKST': -540, // 알래스카 표준시 (UTC-9) + 'HST': -600, // 하와이 표준시 (UTC-10) + 'BRT': -180, // 브라질 표준시 (UTC-3) + 'ART': -180 // 아르헨티나 표준시 (UTC-3) +}; + +/** + * 타임존에 맞는 날짜 생성 + * @param {string} timezone - 타임존 코드 (예: 'KST', 'UTC') + * @returns {Date} 타임존이 적용된 날짜 객체 + */ +function getDateByTimezone(timezone) { + const now = new Date(); + const utcTime = now.getTime() + (now.getTimezoneOffset() * 60 * 1000); + const offsetMinutes = timezoneOffsets[timezone] || 0; + return new Date(utcTime + (offsetMinutes * 60 * 1000)); +} + +/** + * 현재 타임스탬프 문자열 생성 + * @param {string} format - 포맷 (기본값: 'YYYYMMDDHHmmss') + * @returns {string} 타임스탬프 문자열 + */ +function getNowTimestampStr(format = 'YYYYMMDDHHmmss') { + return formatDate(new Date(), format); +} + +module.exports = { + formatDate, + createInClause, + timezoneOffsets, + getDateByTimezone, + getNowTimestampStr +}; + diff --git a/src/utils/messages.js b/src/utils/messages.js new file mode 100644 index 0000000..c2316ce --- /dev/null +++ b/src/utils/messages.js @@ -0,0 +1,165 @@ +/** + * 다국어 메시지 중앙 관리 모듈 + */ + +// 언어 설정 (환경 변수 사용, 기본값 영어) +const LANGUAGE = process.env.LANGUAGE || 'en'; + +/** + * 데이터베이스 관련 메시지 + */ +const databaseMessages = { + en: { + dbIdNotFound: 'DB connection ID not found:', + dbConnecting: 'connecting to database...', + dbConnected: 'database connected', + dbClosing: 'closing database connection', + errorLogin: 'Database login failed: Check username or password.', + errorAuth: 'Database authentication failed: Check username or password.', + errorSocket: 'Database connection failed: Check server address and port.', + errorConnection: 'Database connection failed: Check server address and port.', + errorName: 'Database name error: Check database name.', + errorDatabase: 'Database error: Check database name.', + errorTimeout: 'Query execution timeout: Optimize query or increase timeout.', + errorAlreadyConnected: 'Database already connected.', + errorNotOpen: 'Database connection is not open.', + mssqlError: 'MSSQL Error:', + mysqlError: 'MySQL Error:', + unsupportedDbType: 'Unsupported database type:', + requiredConfigMissing: 'Required configuration is missing:', + portInvalid: 'Port number must be between 1-65535.' + }, + kr: { + dbIdNotFound: 'DB 접속 ID를 찾을 수 없습니다:', + dbConnecting: '데이터베이스에 연결 중...', + dbConnected: '데이터베이스 연결 완료', + dbClosing: '데이터베이스 연결 종료', + errorLogin: '데이터베이스 로그인 실패: 사용자명 또는 비밀번호를 확인하세요.', + errorAuth: '데이터베이스 인증 실패: 사용자명 또는 비밀번호를 확인하세요.', + errorSocket: '데이터베이스 연결 실패: 서버 주소와 포트를 확인하세요.', + errorConnection: '데이터베이스 연결 실패: 서버 주소와 포트를 확인하세요.', + errorName: '데이터베이스 이름 오류: 데이터베이스 이름을 확인하세요.', + errorDatabase: '데이터베이스 오류: 데이터베이스 이름을 확인하세요.', + errorTimeout: '쿼리 실행 시간 초과: 쿼리를 최적화하거나 타임아웃을 늘려주세요.', + errorAlreadyConnected: '이미 연결된 데이터베이스입니다.', + errorNotOpen: '데이터베이스 연결이 열려있지 않습니다.', + mssqlError: 'MSSQL 오류:', + mysqlError: 'MySQL 오류:', + unsupportedDbType: '지원하지 않는 데이터베이스 유형:', + requiredConfigMissing: '필수 설정이 누락되었습니다:', + portInvalid: '포트 번호는 1-65535 사이여야 합니다.' + } +}; + +/** + * 변수 처리 관련 메시지 + */ +const variableMessages = { + en: { + dynamicVarSet: 'Dynamic variable set:', + dynamicVarProcessStart: '\n🔄 Dynamic variable processing started', + dynamicVarProcessing: '\n📊 Processing dynamic variable:', + noDesc: 'no description', + database: ' Database:', + dynamicVarSpecified: 'dynamic variable specified', + default: 'default', + keyValuePairs: ' ✅', + keyValuePairsText: 'key-value pairs', + keyValuePairsNeedMin2Cols: ' ⚠️', + keyValuePairsNeedMin2ColsText: 'key_value_pairs type requires at least 2 columns', + columnsRows: ' ✅', + columnsText: 'columns,', + rowsText: 'rows', + noResults: ' ⚠️', + noResultsText: 'No query results', + processError: ' ❌', + processErrorText: 'Error during processing:', + dynamicVarProcessComplete: '\n✅ Dynamic variable processing completed', + variableSubstStart: 'Variable substitution started:', + dynamicVarSub: 'Dynamic variable', + substituted: 'substituted:', + array: 'array', + toInClause: '→ IN clause', + objectType: 'object type', + errorDuring: 'Error during', + substitution: 'substitution:', + timestampFunc: 'Timestamp function', + generalVar: 'General variable', + envVar: 'Environment variable', + simpleString: '(simple string)', + skipped: 'skipped: already processed variable', + unresolvedVars: 'Unresolved variables:', + unresolvedDynamicVar: 'Unresolved dynamic variable', + replacedWith: '→ replaced with', + unresolvedVar: 'Unresolved variable', + emptyString: '(empty string)', + nullValue: '(no match)' + }, + kr: { + dynamicVarSet: '동적 변수 설정:', + dynamicVarProcessStart: '\n🔄 동적 변수 처리 시작', + dynamicVarProcessing: '\n📊 동적 변수 처리 중:', + noDesc: '설명 없음', + database: ' 데이터베이스:', + dynamicVarSpecified: '동적 변수 지정', + default: '기본', + keyValuePairs: ' ✅', + keyValuePairsText: '키-값 쌍', + keyValuePairsNeedMin2Cols: ' ⚠️', + keyValuePairsNeedMin2ColsText: 'key_value_pairs 타입은 최소 2개의 컬럼이 필요합니다', + columnsRows: ' ✅', + columnsText: '컬럼,', + rowsText: '행', + noResults: ' ⚠️', + noResultsText: '쿼리 결과 없음', + processError: ' ❌', + processErrorText: '처리 중 오류:', + dynamicVarProcessComplete: '\n✅ 동적 변수 처리 완료', + variableSubstStart: '변수 치환 시작:', + dynamicVarSub: '동적 변수', + substituted: '치환됨:', + array: '배열', + toInClause: '→ IN 절', + objectType: '객체 타입', + errorDuring: '오류 발생:', + substitution: '치환:', + timestampFunc: '타임스탬프 함수', + generalVar: '일반 변수', + envVar: '환경 변수', + simpleString: '(단순 문자열)', + skipped: '건너뜀: 이미 처리된 변수', + unresolvedVars: '미해결 변수:', + unresolvedDynamicVar: '미해결 동적 변수', + replacedWith: '→ 교체됨:', + unresolvedVar: '미해결 변수', + emptyString: '(빈 문자열)', + nullValue: '(일치 없음)' + } +}; + +/** + * 메시지 가져오기 함수 + * @param {string} category - 메시지 카테고리 ('database', 'variable') + * @param {string} language - 언어 코드 ('en', 'kr') + * @returns {Object} 해당 카테고리의 메시지 객체 + */ +function getMessages(category, language = LANGUAGE) { + const lang = language || 'en'; + + switch (category) { + case 'database': + return databaseMessages[lang] || databaseMessages.en; + case 'variable': + return variableMessages[lang] || variableMessages.en; + default: + return {}; + } +} + +module.exports = { + getMessages, + databaseMessages, + variableMessages, + LANGUAGE +}; + diff --git a/src/variable-processor.js b/src/variable-processor.js index 3d8bed4..463c862 100644 --- a/src/variable-processor.js +++ b/src/variable-processor.js @@ -1,9 +1,8 @@ -const MSSQLHelper = require('./mssql-helper'); +const { getMessages, LANGUAGE } = require('./utils/messages'); +const { formatDate, createInClause, timezoneOffsets } = require('./utils/date-utils'); -// 언어 설정 (환경 변수 사용, 기본값 영어) -const LANGUAGE = process.env.LANGUAGE || 'en'; - -// 다국어 메시지 +// 다국어 메시지는 utils/messages.js에서 관리 +// 하위 호환성을 위해 여기에 재정의 const messages = { en: { dynamicVarSet: 'Dynamic variable set:', @@ -95,8 +94,21 @@ const msg = messages[LANGUAGE] || messages.en; class VariableProcessor { constructor() { this.dynamicVariables = {}; - this.mssqlHelper = new MSSQLHelper(LANGUAGE); - this.msg = msg; + this.msg = getMessages('variable', LANGUAGE); + } + + /** + * IN 절 생성 유틸리티 (재사용) + */ + createInClause(values) { + return createInClause(values); + } + + /** + * 날짜 포맷팅 함수 (재사용) + */ + formatDate(date, format) { + return formatDate(date, format); } /** @@ -112,12 +124,12 @@ class VariableProcessor { /** * 동적 변수 처리 * @param {Array} dynamicVars - 동적 변수 정의 배열 - * @param {MSSQLHelper} mssqlHelper - MSSQL 헬퍼 인스턴스 + * @param {Object} dbAdapter - 데이터베이스 어댑터 인스턴스 * @param {string} dbKey - 데이터베이스 키 * @param {Object} globalVars - 전역 변수 * @param {Object} configObj - 데이터베이스 설정 객체 */ - async processDynamicVariables(dynamicVars, mssqlHelper, dbKey, globalVars, configObj) { + async processDynamicVariables(dynamicVars, dbAdapter, dbKey, globalVars, configObj) { // 동적 변수 초기화 this.dynamicVariables = {}; @@ -137,8 +149,8 @@ class VariableProcessor { console.log(`${this.msg.database} ${targetDbKey} (${dynamicVar.database ? this.msg.dynamicVarSpecified : this.msg.default})`); // DB에서 데이터 조회 - const pool = await mssqlHelper.createConnectionPool(configObj[targetDbKey], targetDbKey); - const result = await mssqlHelper.executeQuery(pool, processedQuery); + const pool = await dbAdapter.createConnectionPool(configObj[targetDbKey], targetDbKey); + const result = await dbAdapter.executeQuery(pool, processedQuery); if (result.recordset && result.recordset.length > 0) { const data = result.recordset; @@ -295,32 +307,7 @@ class VariableProcessor { } }); - // 타임존별 오프셋 설정 (UTC 기준, 분 단위) - const timezoneOffsets = { - 'UTC': 0, // 협정 세계시 - 'GMT': 0, // 그리니치 표준시 (UTC와 동일) - 'KST': 540, // 한국 표준시 (UTC+9) - 'JST': 540, // 일본 표준시 (UTC+9) - 'CST': 480, // 중국 표준시 (UTC+8) - 'SGT': 480, // 싱가포르 표준시 (UTC+8) - 'PHT': 480, // 필리핀 표준시 (UTC+8) - 'AEST': 600, // 호주 동부 표준시 (UTC+10) - 'ICT': 420, // 인도차이나 표준시 (UTC+7) - 태국, 베트남 - 'CET': 60, // 중앙 유럽 표준시 (UTC+1) - 독일, 프랑스, 이탈리아, 폴란드 - 'EET': 120, // 동유럽 표준시 (UTC+2) - 'IST': 330, // 인도 표준시 (UTC+5:30) - 'GST': 240, // 걸프 표준시 (UTC+4) - 'EST': -300, // 미국 동부 표준시 (UTC-5) - 'CST_US': -360, // 미국/캐나다/멕시코 중부 표준시 (UTC-6) - 'MST': -420, // 미국 산악 표준시 (UTC-7) - 'PST': -480, // 미국 서부 표준시 (UTC-8) - 'AST': -240, // 대서양 표준시 (UTC-4) - 캐나다 동부 - 'AKST': -540, // 알래스카 표준시 (UTC-9) - 'HST': -600, // 하와이 표준시 (UTC-10) - 'BRT': -180, // 브라질 표준시 (UTC-3) - 'ART': -180 // 아르헨티나 표준시 (UTC-3) - }; - + // 타임존별 오프셋은 utils/date-utils.js에서 관리 // 타임존 지정 없는 로컬 날짜 변수 치환 (예: ${DATE:YYYY-MM-DD}) const localDatePattern = /\$\{DATE:([^}]+)\}/g; let localDateMatch; From d828fdb9633f8d2c0aa225bd8accce51c788d7dc Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:14:01 +0900 Subject: [PATCH 02/25] Added sample queries for mysql/mariadb --- queries/mariadb-test.xml | 69 +++++++++++++++++ queries/mysql-simple-test.json | 34 +++++++++ queries/mysql-test-queries.xml | 130 +++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 queries/mariadb-test.xml create mode 100644 queries/mysql-simple-test.json create mode 100644 queries/mysql-test-queries.xml diff --git a/queries/mariadb-test.xml b/queries/mariadb-test.xml new file mode 100644 index 0000000..5b459e3 --- /dev/null +++ b/queries/mariadb-test.xml @@ -0,0 +1,69 @@ + + + + + + + + + SELECT + '서울' as city, + '${DATE.KST:YYYY년 MM월 DD일 HH시 mm분 ss초}' as time + UNION ALL + SELECT '뉴욕', '${DATE.EST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT '런던', '${DATE.GMT:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT '도쿄', '${DATE.JST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT '시드니', '${DATE.AEST:YYYY-MM-DD HH:mm:ss}' + + + + + + SELECT + SCHEMA_NAME as '데이터베이스명', + DEFAULT_CHARACTER_SET_NAME as '문자셋', + DEFAULT_COLLATION_NAME as '콜레이션' + FROM information_schema.SCHEMATA + WHERE SCHEMA_NAME NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') + ORDER BY SCHEMA_NAME + + + + + + SELECT + TABLE_SCHEMA as '데이터베이스', + TABLE_NAME as '테이블명', + TABLE_ROWS as '행수', + ROUND(DATA_LENGTH / 1024 / 1024, 2) as '데이터크기_MB', + ROUND(INDEX_LENGTH / 1024 / 1024, 2) as '인덱스크기_MB', + ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) as '총크기_MB' + FROM information_schema.TABLES + WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') + ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC + LIMIT 50 + + + + + + SELECT + VARIABLE_NAME as '변수명', + VARIABLE_VALUE as '값' + FROM information_schema.GLOBAL_VARIABLES + WHERE VARIABLE_NAME LIKE '%version%' + OR VARIABLE_NAME LIKE '%character%' + OR VARIABLE_NAME LIKE '%collation%' + ORDER BY VARIABLE_NAME + LIMIT 30 + + + + + diff --git a/queries/mysql-simple-test.json b/queries/mysql-simple-test.json new file mode 100644 index 0000000..fcf5054 --- /dev/null +++ b/queries/mysql-simple-test.json @@ -0,0 +1,34 @@ +{ + "excel": { + "output": "output/mysql_simple_${DATE.KST:YYYYMMDD}.xlsx", + "db": "mysql", + "style": "default" + }, + "globalVars": { + "reportTitle": "MySQL Database Report", + "reportDate": "2024" + }, + "sheets": [ + { + "name": "Database Info", + "db": "mysql", + "query": "SELECT SCHEMA_NAME as db_name, DEFAULT_CHARACTER_SET_NAME as charset, DEFAULT_COLLATION_NAME as collation FROM information_schema.SCHEMATA ORDER BY SCHEMA_NAME LIMIT 20" + }, + { + "name": "MySQL Version", + "db": "mysql", + "query": "SELECT @@version as version, @@version_comment as comment, NOW() as `current_time`" + }, + { + "name": "Table Statistics", + "db": "mysql", + "query": "SELECT TABLE_SCHEMA as db_name, COUNT(*) as table_count, SUM(TABLE_ROWS) as total_rows FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') GROUP BY TABLE_SCHEMA" + }, + { + "name": "MSSQL Test", + "db": "sampleDB", + "query": "SELECT TOP 5 name, database_id, create_date FROM sys.databases ORDER BY name" + } + ] +} + diff --git a/queries/mysql-test-queries.xml b/queries/mysql-test-queries.xml new file mode 100644 index 0000000..23890d1 --- /dev/null +++ b/queries/mysql-test-queries.xml @@ -0,0 +1,130 @@ + + + + + + + + + + SELECT + SCHEMA_NAME as database_name, + DEFAULT_CHARACTER_SET_NAME as charset, + DEFAULT_COLLATION_NAME as collation, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as report_date + FROM information_schema.SCHEMATA + ORDER BY SCHEMA_NAME + + + + + + + SELECT + TABLE_SCHEMA as database_name, + TABLE_NAME as table_name, + TABLE_TYPE as table_type, + ENGINE as engine, + TABLE_ROWS as row_count, + ROUND(DATA_LENGTH / 1024 / 1024, 2) as data_size_mb, + ROUND(INDEX_LENGTH / 1024 / 1024, 2) as index_size_mb, + CREATE_TIME as created_at + FROM information_schema.TABLES + WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') + ORDER BY TABLE_SCHEMA, TABLE_NAME + LIMIT 100 + + + + + + + SELECT + User as username, + Host as host, + '${DATE.UTC:YYYY-MM-DD}' as report_date_utc, + '${DATE.KST:YYYY-MM-DD}' as report_date_kst + FROM mysql.user + ORDER BY User, Host + + + + + + + SELECT + VARIABLE_NAME as variable_name, + VARIABLE_VALUE as value + FROM information_schema.GLOBAL_VARIABLES + WHERE VARIABLE_NAME IN ( + 'version', + 'version_comment', + 'max_connections', + 'character_set_server', + 'collation_server', + 'innodb_buffer_pool_size', + 'datadir' + ) + ORDER BY VARIABLE_NAME + + + + + + + SELECT + TABLE_SCHEMA as database_name, + COUNT(*) as table_count, + SUM(TABLE_ROWS) as total_rows, + ROUND(SUM(DATA_LENGTH) / 1024 / 1024, 2) as total_data_mb, + '${DATE:YYYY년 MM월 DD일 HH시 mm분}' as report_time + FROM information_schema.TABLES + WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') + GROUP BY TABLE_SCHEMA + ORDER BY total_data_mb DESC + + + + + + + SELECT TOP 10 + name as database_name, + database_id, + create_date, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as report_date + FROM sys.databases + ORDER BY name + + + + + + + SELECT + 'Seoul (KST)' as timezone, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as datetime + UNION ALL + SELECT + 'UTC', + '${DATE.UTC:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'New York (EST)', + '${DATE.EST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'Tokyo (JST)', + '${DATE.JST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'Local Time', + '${DATE:YYYY-MM-DD HH:mm:ss}' + + + + + From 15e8118b8132719106fa307b9c435015e3922102 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:14:52 +0900 Subject: [PATCH 03/25] Fix the problem --- src/index.js | 2 ++ src/query-parser.js | 8 +++++++- src/variable-processor.js | 18 +++++++++--------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/index.js b/src/index.js index ea62486..28f7296 100644 --- a/src/index.js +++ b/src/index.js @@ -260,6 +260,8 @@ async function main() { // 엑셀 파일 경로 결정 (CLI > excel > 쿼리파일 > 기본값) let outFile = argv.out || excelOutput || outputPath || 'output.xlsx'; + // 파일명에 포함된 변수 치환 (예: ${DATE.KST:YYYYMMDD}) + outFile = variableProcessor.substituteVars(outFile, mergedVars); outFile = FileUtils.resolvePath(outFile); // 파일명에 _yyyymmddhhmmss 추가 outFile = excelGenerator.generateOutputPath(outFile, FileUtils.getNowTimestampStr()); diff --git a/src/query-parser.js b/src/query-parser.js index 397fce4..e235ce0 100644 --- a/src/query-parser.js +++ b/src/query-parser.js @@ -410,7 +410,13 @@ class QueryParser { } } else { // 직접 쿼리가 있으면 사용 - query = (s._ || (s["_"] ? s["_"] : (s["$"] ? s["$"] : '')) || (s["__cdata"] ? s["__cdata"] : '') || (s["cdata"] ? s["cdata"] : '') || (s["#cdata-section"] ? s["#cdata-section"] : '') || (s["__text"] ? s["__text"] : '') || (s["#text"] ? s["#text"] : '') || (s["$text"] ? s["$text"] : '') || (s["$value"] ? s["$value"] : '') || (s["value"] ? s["value"] : '') || '').toString().trim(); + // 태그가 있는 경우: s.query[0] + if (s.query && s.query[0]) { + query = (typeof s.query[0] === 'string' ? s.query[0] : (s.query[0]._ || s.query[0]['#text'] || '')).toString().trim(); + } else { + // 직접 텍스트로 작성된 경우: s._ + query = (s._ || (s["_"] ? s["_"] : (s["$"] ? s["$"] : '')) || (s["__cdata"] ? s["__cdata"] : '') || (s["cdata"] ? s["cdata"] : '') || (s["#cdata-section"] ? s["#cdata-section"] : '') || (s["__text"] ? s["__text"] : '') || (s["#text"] ? s["#text"] : '') || (s["$text"] ? s["$text"] : '') || (s["$value"] ? s["$value"] : '') || (s["value"] ? s["value"] : '') || '').toString().trim(); + } } return { diff --git a/src/variable-processor.js b/src/variable-processor.js index 463c862..fa00bd7 100644 --- a/src/variable-processor.js +++ b/src/variable-processor.js @@ -241,7 +241,7 @@ class VariableProcessor { try { // 배열 타입인 경우 IN절 처리 if (Array.isArray(value)) { - const inClause = this.mssqlHelper.createInClause(value); + const inClause = this.createInClause(value); result = result.replace(pattern, inClause); if (debugVariables && beforeReplace !== result) { @@ -258,12 +258,12 @@ class VariableProcessor { if (Array.isArray(keyValue)) { // column_identified: 배열 값을 IN절로 변환 - const inClause = this.mssqlHelper.createInClause(keyValue); + const inClause = this.createInClause(keyValue); result = result.replace(keyPattern, inClause); } else { // key_value_pairs: 키 값들을 배열로 반환 (IN절용) if (Array.isArray(keyValue)) { - const inClause = this.mssqlHelper.createInClause(keyValue); + const inClause = this.createInClause(keyValue); result = result.replace(keyPattern, inClause); } else { // 단일 값인 경우 @@ -282,11 +282,11 @@ class VariableProcessor { if (allValues.every(v => Array.isArray(v))) { // column_identified: 모든 배열 값을 통합하여 IN절로 const flatValues = allValues.flat(); - const inClause = this.mssqlHelper.createInClause(flatValues); + const inClause = this.createInClause(flatValues); result = result.replace(pattern, inClause); } else { // key_value_pairs: 모든 값들을 IN절로 - const inClause = this.mssqlHelper.createInClause(allValues); + const inClause = this.createInClause(allValues); result = result.replace(pattern, inClause); } @@ -318,7 +318,7 @@ class VariableProcessor { try { // 로컬 시간 사용 (시스템 타임존) const now = new Date(); - const formattedDate = this.mssqlHelper.formatDate(now, format); + const formattedDate = this.formatDate(now, format); result = result.replace(fullMatch, formattedDate); if (debugVariables) { @@ -347,7 +347,7 @@ class VariableProcessor { // 타임존 오프셋을 적용한 날짜 계산 const date = new Date(now.getTime() + (offsetMinutes * 60 * 1000)); - const formattedDate = this.mssqlHelper.formatDate(date, format); + const formattedDate = this.formatDate(date, format); result = result.replace(fullMatch, formattedDate); if (debugVariables) { @@ -366,7 +366,7 @@ class VariableProcessor { // 배열 타입인 경우 IN절 처리 if (Array.isArray(value)) { - const inClause = this.mssqlHelper.createInClause(value); + const inClause = this.createInClause(value); if (debugVariables) { console.log(`${this.msg.generalVar} [${v}] ${this.msg.substituted} ${this.msg.array} ${value.length}개 ${this.msg.toInClause}`); @@ -402,7 +402,7 @@ class VariableProcessor { // 환경 변수가 배열 형태인지 확인 (JSON 형태로 저장된 경우) const parsed = JSON.parse(envValue); if (Array.isArray(parsed)) { - const inClause = this.mssqlHelper.createInClause(parsed); + const inClause = this.createInClause(parsed); result = result.replace(fullMatch, inClause); if (debugVariables) { From bca869be721a3fd6f0958ebd73259b641f016360 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:26:49 +0900 Subject: [PATCH 04/25] Modified sample query --- queries/queries-with-dynamic-variables.xml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/queries/queries-with-dynamic-variables.xml b/queries/queries-with-dynamic-variables.xml index 31503a6..8734d05 100644 --- a/queries/queries-with-dynamic-variables.xml +++ b/queries/queries-with-dynamic-variables.xml @@ -71,8 +71,7 @@ c.Region as Region, c.CustomerType as CustomerType FROM SampleDB.dbo.Customers c - WHERE c.CustomerID IN (${customerData.CustomerID}) - AND c.Region IN (${regionList}) + WHERE c.Region IN (${regionList}) ORDER BY c.CustomerID ]]> @@ -82,15 +81,10 @@ - ["Seoul", "Busan"] + ["서울", "부산"] - - - ["Busan"] - - Date: Wed, 22 Oct 2025 12:32:07 +0900 Subject: [PATCH 05/25] Update document for v1.3.0 --- CHANGELOG.md | 89 ++++++++++++++++++++++ CHANGELOG_KR.md | 89 ++++++++++++++++++++++ README.md | 63 ++++++++++------ README_KR.md | 63 ++++++++++------ USER_MANUAL.md | 189 ++++++++++++++++++++++++++++++++++++++++------ USER_MANUAL_KR.md | 189 ++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 590 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6867a7..34f75da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,94 @@ # SQL2Excel Version History +## v1.3.0 - Multi-Database Support (2025-10-22) + +### ✨ New Features +- **Multi-Database Support**: Support for multiple database types beyond MSSQL + - **Supported Databases**: MSSQL, MySQL, MariaDB + - **Unified Interface**: Consistent API across all database types + - **Database Factory Pattern**: Automatic adapter selection based on database type + - **Backward Compatibility**: Existing MSSQL configurations work without changes + +### 🔧 Configuration +```json +{ + "sampleDB": { + "type": "mssql", // Optional, defaults to "mssql" if not specified + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "password" + }, + "mysqlDB": { + "type": "mysql", // New: MySQL support + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "mariaDB": { + "type": "mariadb", // New: MariaDB support + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + } +} +``` + +### 📦 Technical Changes +- **New Architecture**: + - `src/database/DatabaseFactory.js`: Factory for creating database adapters + - `src/database/MSSQLAdapter.js`: MSSQL implementation (refactored from mssql-helper.js) + - `src/database/MySQLAdapter.js`: MySQL/MariaDB implementation + +- **Updated Files**: + - `src/index.js`: Uses DatabaseFactory instead of direct MSSQLHelper + - `src/variable-processor.js`: Database-agnostic implementation + - `package.json`: Added `mysql2` dependency + +### 🔄 Database-Specific Features +- **MSSQL**: + - Uses `TOP N` for row limiting + - Supports `GETDATE()` function + +- **MySQL/MariaDB**: + - Uses `LIMIT N` for row limiting + - Converts `GETDATE()` to `NOW()` automatically + - Connection pooling with automatic reconnection + +### 💡 Usage Examples +```xml + + + + SELECT * FROM users + + + + SELECT * FROM orders + + + + SELECT * FROM products + + +``` + +### ⚠️ Notes +- **Type Field**: The `type` field in database configuration is optional. If omitted, defaults to `mssql` for backward compatibility. +- **Port Numbers**: Default ports are used if not specified (MSSQL: 1433, MySQL/MariaDB: 3306) +- **Connection Pooling**: All database types use connection pooling for optimal performance + +### 📚 Dependencies +- Added: `mysql2@^3.6.0` - MySQL/MariaDB driver with promise support +- Maintained: `mssql@^10.0.0` - Microsoft SQL Server driver + +--- + ## v1.2.9 - Global Timezone System & Local Time Support (2025-10-21) ### ✨ New Features diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index 69f8219..c6f3383 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -1,5 +1,94 @@ # SQL2Excel 버전 히스토리 +## v1.3.0 - 다중 데이터베이스 지원 (2025-10-22) + +### ✨ 새로운 기능 +- **다중 데이터베이스 지원**: MSSQL 외 다양한 데이터베이스 타입 지원 + - **지원 데이터베이스**: MSSQL, MySQL, MariaDB + - **통합 인터페이스**: 모든 데이터베이스 타입에 대한 일관된 API + - **데이터베이스 팩토리 패턴**: 데이터베이스 타입에 따라 자동으로 적절한 어댑터 선택 + - **하위 호환성**: 기존 MSSQL 설정은 변경 없이 그대로 작동 + +### 🔧 설정 +```json +{ + "sampleDB": { + "type": "mssql", // 선택사항, 지정하지 않으면 "mssql" 기본값 사용 + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "password" + }, + "mysqlDB": { + "type": "mysql", // 신규: MySQL 지원 + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "mariaDB": { + "type": "mariadb", // 신규: MariaDB 지원 + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + } +} +``` + +### 📦 기술적 변경사항 +- **새로운 아키텍처**: + - `src/database/DatabaseFactory.js`: 데이터베이스 어댑터 생성 팩토리 + - `src/database/MSSQLAdapter.js`: MSSQL 구현 (mssql-helper.js에서 리팩토링) + - `src/database/MySQLAdapter.js`: MySQL/MariaDB 구현 + +- **업데이트된 파일**: + - `src/index.js`: MSSQLHelper 대신 DatabaseFactory 사용 + - `src/variable-processor.js`: 데이터베이스 독립적인 구현 + - `package.json`: `mysql2` 의존성 추가 + +### 🔄 데이터베이스별 특징 +- **MSSQL**: + - 행 제한에 `TOP N` 사용 + - `GETDATE()` 함수 지원 + +- **MySQL/MariaDB**: + - 행 제한에 `LIMIT N` 사용 + - `GETDATE()`를 `NOW()`로 자동 변환 + - 자동 재연결 기능이 있는 연결 풀링 + +### 💡 사용 예시 +```xml + + + + SELECT * FROM users + + + + SELECT * FROM orders + + + + SELECT * FROM products + + +``` + +### ⚠️ 참고사항 +- **Type 필드**: 데이터베이스 설정의 `type` 필드는 선택사항입니다. 생략하면 하위 호환성을 위해 `mssql`을 기본값으로 사용합니다. +- **포트 번호**: 지정하지 않으면 기본 포트를 사용합니다 (MSSQL: 1433, MySQL/MariaDB: 3306) +- **연결 풀링**: 모든 데이터베이스 타입은 최적의 성능을 위해 연결 풀링을 사용합니다 + +### 📚 의존성 +- 추가: `mysql2@^3.6.0` - Promise 지원이 포함된 MySQL/MariaDB 드라이버 +- 유지: `mssql@^10.0.0` - Microsoft SQL Server 드라이버 + +--- + ## v1.2.9 - 글로벌 타임존 시스템 및 로컬 시간 지원 (2025-10-21) ### ✨ 새로운 기능 diff --git a/README.md b/README.md index 6e3d0f3..1910740 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet +- 🗄️ **Multi-Database Support (v1.3.0)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -33,12 +34,12 @@ A Node.js-based tool for generating Excel files from SQL query results. #### For Development/Source Code Usage - Node.js 16.0 or higher -- SQL Server 2012 or higher +- Database Server (MSSQL 2012+, MySQL 5.7+, or MariaDB 10.2+) - Appropriate database permissions #### For Standalone Executable Usage - Windows 10 or higher (64-bit) -- SQL Server 2012 or higher +- Database Server (MSSQL 2012+, MySQL 5.7+, or MariaDB 10.2+) - Appropriate database permissions - **No Node.js installation required** @@ -65,33 +66,47 @@ npm run build Create `config/dbinfo.json` file: ```json { - "dbs": { - "sampleDB": { - "server": "localhost", - "port": 1433, - "database": "SampleDB", - "user": "sa", - "password": "yourpassword", - "options": { - "encrypt": false, - "trustServerCertificate": true - } - }, - "erpDB": { - "server": "erp-server.com", - "port": 1433, - "database": "ERP_Database", - "user": "erp_user", - "password": "erp_password", - "options": { - "encrypt": true, - "trustServerCertificate": false - } + "sampleDB": { + "type": "mssql", + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "yourpassword", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 + } + }, + "mariaDB": { + "type": "mariadb", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 } } } ``` +**Note:** +- `type` field is optional. If not specified, defaults to `mssql` for backward compatibility. +- Supported types: `mssql`, `mysql`, `mariadb` + ## 🚀 Basic Usage ### Language Settings diff --git a/README_KR.md b/README_KR.md index ed84416..6cf0017 100644 --- a/README_KR.md +++ b/README_KR.md @@ -6,6 +6,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 +- 🗄️ **다중 데이터베이스 지원 (v1.3.0)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -33,12 +34,12 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 #### 개발/소스 코드 사용 시 - Node.js 16.0 이상 -- SQL Server 2012 이상 +- 데이터베이스 서버 (MSSQL 2012+, MySQL 5.7+, 또는 MariaDB 10.2+) - 적절한 데이터베이스 권한 #### 독립 실행 파일 사용 시 - Windows 10 이상 (64비트) -- SQL Server 2012 이상 +- 데이터베이스 서버 (MSSQL 2012+, MySQL 5.7+, 또는 MariaDB 10.2+) - 적절한 데이터베이스 권한 - **Node.js 설치 불필요** @@ -65,33 +66,47 @@ npm run build `config/dbinfo.json` 파일을 생성하세요: ```json { - "dbs": { - "sampleDB": { - "server": "localhost", - "port": 1433, - "database": "SampleDB", - "user": "sa", - "password": "yourpassword", - "options": { - "encrypt": false, - "trustServerCertificate": true - } - }, - "erpDB": { - "server": "erp-server.com", - "port": 1433, - "database": "ERP_Database", - "user": "erp_user", - "password": "erp_password", - "options": { - "encrypt": true, - "trustServerCertificate": false - } + "sampleDB": { + "type": "mssql", + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "yourpassword", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 + } + }, + "mariaDB": { + "type": "mariadb", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 } } } ``` +**참고:** +- `type` 필드는 선택사항입니다. 지정하지 않으면 하위 호환성을 위해 기본값 `mssql`을 사용합니다. +- 지원 타입: `mssql`, `mysql`, `mariadb` + ## 🚀 기본 사용법 ### 언어 설정 diff --git a/USER_MANUAL.md b/USER_MANUAL.md index 7f40412..724a231 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -23,6 +23,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet +- 🗄️ **Multi-Database Support (v1.3.0)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -38,7 +39,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 🌐 **Multi-language Support**: Korean and English release packages - 🔧 **Release Automation**: Automated release package generation with proper documentation - 🕒 **Creation Timestamp**: Display creation timestamp on each Excel sheet -- ⏰ **Enhanced DateTime Variables**: 20+ automatic datetime variables for real-time timestamp generation +- ⏰ **Enhanced DateTime Variables**: 22 timezones worldwide with custom format support - 📋 **SQL Query Formatting**: Preserve original SQL formatting with line breaks in Table of Contents - 🔧 **Input Validation**: Automatic whitespace trimming for file path inputs @@ -48,12 +49,12 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q #### For Development/Source Code Usage - Node.js 16.0 or higher -- SQL Server 2012 or higher +- Database Server (MSSQL 2012+, MySQL 5.7+, or MariaDB 10.2+) - Appropriate database permissions #### For Standalone Executable Usage - Windows 10 or higher (64-bit) -- SQL Server 2012 or higher +- Database Server (MSSQL 2012+, MySQL 5.7+, or MariaDB 10.2+) - Appropriate database permissions - **No Node.js installation required** @@ -78,26 +79,47 @@ npm run build ### 3. Database Connection Setup Create `config/dbinfo.json` file: + +#### Multi-Database Support (v1.3.0+) ```json { - "dbs": { - "sampleDB": { - "server": "localhost", - "port": 1433, - "database": "SampleDB", - "user": "sa", - "password": "yourpassword", - "options": { - "encrypt": false, - "trustServerCertificate": true - } - }, - "erpDB": { - "server": "erp-server.com", - "port": 1433, - "database": "ERP_Database", - "user": "erp_user", - "password": "erp_password", + "sampleDB": { + "type": "mssql", // Optional: "mssql" (default), "mysql", or "mariadb" + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "yourpassword", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", // MySQL database + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 + } + }, + "mariaDB": { + "type": "mariadb", // MariaDB database + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "erpDB": { + "server": "erp-server.com", + "port": 1433, + "database": "ERP_Database", + "user": "erp_user", + "password": "erp_password", "options": { "encrypt": true, "trustServerCertificate": false @@ -687,7 +709,130 @@ This feature works automatically - no configuration required! ## 🎨 Advanced Features -### 1. Excel Styling +### 1. Multi-Database Support (v1.3.0+) + +SQL2Excel now supports multiple database types with a unified interface: + +#### Supported Databases +- **MSSQL** (SQL Server 2012+) +- **MySQL** (5.7+) +- **MariaDB** (10.2+) + +#### Configuration +Add the `type` field to your database connection in `config/dbinfo.json`: + +```json +{ + "mssqlDB": { + "type": "mssql", // or omit for backward compatibility + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "password", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "mariaDB": { + "type": "mariadb", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + } +} +``` + +#### Mixed Database Queries +You can query different database types in a single Excel file: + +**XML Example:** +```xml + + + + + + + + + SELECT TOP 10 * FROM Customers + + + + + + + SELECT * FROM products LIMIT 10 + + + + + + + SELECT * FROM orders + WHERE order_date >= '2024-01-01' + LIMIT 20 + + + +``` + +**JSON Example:** +```json +{ + "excel": { + "output": "output/mixed_report.xlsx", + "db": "mssqlDB", + "style": "modern" + }, + "sheets": [ + { + "name": "MSSQL Data", + "db": "mssqlDB", + "query": "SELECT TOP 10 * FROM Customers" + }, + { + "name": "MySQL Data", + "db": "mysqlDB", + "query": "SELECT * FROM products LIMIT 10" + }, + { + "name": "MariaDB Data", + "db": "mariaDB", + "query": "SELECT * FROM orders WHERE order_date >= '2024-01-01' LIMIT 20" + } + ] +} +``` + +#### Database-Specific Features +- **MSSQL**: Supports `TOP N` clause, `GETDATE()` function +- **MySQL/MariaDB**: Supports `LIMIT N` clause, `NOW()` function +- **All**: Automatic syntax handling for each database type + +#### Testing Database Connections +Test all configured database connections: +```bash +# Development +node src/excel-cli.js list-dbs + +# Standalone executable +sql2excel-v1.3.0.exe list-dbs +``` + +### 2. Excel Styling #### Font Styling ```xml diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index 8ed1b6d..9c0d13e 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -23,6 +23,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 +- 🗄️ **다중 데이터베이스 지원 (v1.3.0)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -38,7 +39,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 🌐 **다국어 지원**: 한국어 및 영어 릴리스 패키지 - 🔧 **릴리스 자동화**: 적절한 문서와 함께 자동 릴리스 패키지 생성 - 🕒 **생성 타임스탬프**: 각 엑셀 시트에 생성 타임스탬프 표시 -- ⏰ **향상된 DateTime 변수**: 실시간 타임스탬프 생성을 위한 20개 이상의 자동 datetime 변수 +- ⏰ **향상된 DateTime 변수**: 전세계 22개 타임존 지원 및 커스텀 포맷 - 📋 **SQL 쿼리 포맷팅**: 목차에서 줄바꿈을 포함한 원본 SQL 포맷 유지 - 🔧 **입력 유효성 검증**: 파일 경로 입력에 대한 자동 공백 제거 @@ -48,12 +49,12 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 #### 개발/소스 코드 사용 시 - Node.js 16.0 이상 -- SQL Server 2012 이상 +- 데이터베이스 서버 (MSSQL 2012+, MySQL 5.7+, 또는 MariaDB 10.2+) - 적절한 데이터베이스 권한 #### 독립 실행 파일 사용 시 - Windows 10 이상 (64비트) -- SQL Server 2012 이상 +- 데이터베이스 서버 (MSSQL 2012+, MySQL 5.7+, 또는 MariaDB 10.2+) - 적절한 데이터베이스 권한 - **Node.js 설치 불필요** @@ -78,26 +79,47 @@ npm run build ### 3. 데이터베이스 연결 설정 `config/dbinfo.json` 파일을 생성하세요: + +#### 다중 데이터베이스 지원 (v1.3.0+) ```json { - "dbs": { - "sampleDB": { - "server": "localhost", - "port": 1433, - "database": "SampleDB", - "user": "sa", - "password": "yourpassword", - "options": { - "encrypt": false, - "trustServerCertificate": true - } - }, - "erpDB": { - "server": "erp-server.com", - "port": 1433, - "database": "ERP_Database", - "user": "erp_user", - "password": "erp_password", + "sampleDB": { + "type": "mssql", // 선택사항: "mssql" (기본값), "mysql", 또는 "mariadb" + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "yourpassword", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", // MySQL 데이터베이스 + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password", + "options": { + "connectionTimeout": 30000 + } + }, + "mariaDB": { + "type": "mariadb", // MariaDB 데이터베이스 + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "erpDB": { + "server": "erp-server.com", + "port": 1433, + "database": "ERP_Database", + "user": "erp_user", + "password": "erp_password", "options": { "encrypt": true, "trustServerCertificate": false @@ -687,7 +709,130 @@ SQL2Excel은 생성된 각 엑셀 시트에 자동으로 생성 타임스탬프 ## 🎨 고급 기능 -### 1. 엑셀 스타일링 +### 1. 다중 데이터베이스 지원 (v1.3.0+) + +SQL2Excel은 이제 통합 인터페이스로 여러 데이터베이스 타입을 지원합니다: + +#### 지원 데이터베이스 +- **MSSQL** (SQL Server 2012+) +- **MySQL** (5.7+) +- **MariaDB** (10.2+) + +#### 설정 +`config/dbinfo.json`의 데이터베이스 연결에 `type` 필드를 추가하세요: + +```json +{ + "mssqlDB": { + "type": "mssql", // 또는 하위 호환성을 위해 생략 가능 + "server": "localhost", + "port": 1433, + "database": "SampleDB", + "user": "sa", + "password": "password", + "options": { + "encrypt": false, + "trustServerCertificate": true + } + }, + "mysqlDB": { + "type": "mysql", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + }, + "mariaDB": { + "type": "mariadb", + "server": "localhost", + "port": 3306, + "database": "mydb", + "user": "root", + "password": "password" + } +} +``` + +#### 혼합 데이터베이스 쿼리 +단일 Excel 파일에서 다양한 데이터베이스 타입을 쿼리할 수 있습니다: + +**XML 예제:** +```xml + + + + + + + + + SELECT TOP 10 * FROM Customers + + + + + + + SELECT * FROM products LIMIT 10 + + + + + + + SELECT * FROM orders + WHERE order_date >= '2024-01-01' + LIMIT 20 + + + +``` + +**JSON 예제:** +```json +{ + "excel": { + "output": "output/mixed_report.xlsx", + "db": "mssqlDB", + "style": "modern" + }, + "sheets": [ + { + "name": "MSSQL 데이터", + "db": "mssqlDB", + "query": "SELECT TOP 10 * FROM Customers" + }, + { + "name": "MySQL 데이터", + "db": "mysqlDB", + "query": "SELECT * FROM products LIMIT 10" + }, + { + "name": "MariaDB 데이터", + "db": "mariaDB", + "query": "SELECT * FROM orders WHERE order_date >= '2024-01-01' LIMIT 20" + } + ] +} +``` + +#### 데이터베이스별 기능 +- **MSSQL**: `TOP N` 절, `GETDATE()` 함수 지원 +- **MySQL/MariaDB**: `LIMIT N` 절, `NOW()` 함수 지원 +- **전체**: 각 데이터베이스 타입에 대한 자동 구문 처리 + +#### 데이터베이스 연결 테스트 +구성된 모든 데이터베이스 연결을 테스트하세요: +```bash +# 개발 환경 +node src/excel-cli.js list-dbs + +# 독립 실행 파일 +sql2excel-v1.3.0.exe list-dbs +``` + +### 2. 엑셀 스타일링 #### 글꼴 스타일링 ```xml From e9bfd8fdd95224fcc2f2a5d93fdb575911b76649 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:32:39 +0900 Subject: [PATCH 06/25] Removed lagacy source --- src/mssql-helper.js | 236 -------------------------------------------- 1 file changed, 236 deletions(-) delete mode 100644 src/mssql-helper.js diff --git a/src/mssql-helper.js b/src/mssql-helper.js deleted file mode 100644 index df18fc2..0000000 --- a/src/mssql-helper.js +++ /dev/null @@ -1,236 +0,0 @@ -const mssql = require('mssql'); - -// 다국어 메시지 -const messages = { - en: { - dbIdNotFound: 'DB connection ID not found:', - dbConnecting: 'connecting to database...', - dbConnected: 'database connected', - dbClosing: 'closing database connection', - errorLogin: 'Database login failed: Check username or password.', - errorSocket: 'Database connection failed: Check server address and port.', - errorName: 'Database name error: Check database name.', - errorTimeout: 'Query execution timeout: Optimize query or increase timeout.', - errorAlreadyConnected: 'Database already connected.', - errorNotOpen: 'Database connection is not open.', - mssqlError: 'MSSQL Error:' - }, - kr: { - dbIdNotFound: 'DB 접속 ID를 찾을 수 없습니다:', - dbConnecting: '데이터베이스에 연결 중...', - dbConnected: '데이터베이스 연결 완료', - dbClosing: '데이터베이스 연결 종료', - errorLogin: '데이터베이스 로그인 실패: 사용자명 또는 비밀번호를 확인하세요.', - errorSocket: '데이터베이스 연결 실패: 서버 주소와 포트를 확인하세요.', - errorName: '데이터베이스 이름 오류: 데이터베이스 이름을 확인하세요.', - errorTimeout: '쿼리 실행 시간 초과: 쿼리를 최적화하거나 타임아웃을 늘려주세요.', - errorAlreadyConnected: '이미 연결된 데이터베이스입니다.', - errorNotOpen: '데이터베이스 연결이 열려있지 않습니다.', - mssqlError: 'MSSQL 오류:' - } -}; - -/** - * MSSQL 특화 기능들을 담당하는 헬퍼 모듈 - */ -class MSSQLHelper { - constructor(language = 'en') { - this.dbPools = {}; - this.msg = messages[language] || messages.en; - } - - /** - * MSSQL 연결 풀 생성 - * @param {Object} config - MSSQL 연결 설정 - * @param {string} dbKey - 데이터베이스 키 - * @returns {Promise} 연결 풀 - */ - async createConnectionPool(config, dbKey) { - if (!this.dbPools[dbKey]) { - if (!config) { - throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); - } - - console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); - const pool = new mssql.ConnectionPool(config); - await pool.connect(); - this.dbPools[dbKey] = pool; - console.log(`[DB] ${dbKey} ${this.msg.dbConnected}`); - } - return this.dbPools[dbKey]; - } - - /** - * MSSQL 쿼리 실행 - * @param {mssql.ConnectionPool} pool - 연결 풀 - * @param {string} sql - SQL 쿼리 - * @returns {Promise} 쿼리 결과 - */ - async executeQuery(pool, sql) { - return await pool.request().query(sql); - } - - /** - * MSSQL TOP 절 추가 (MSSQL 특화) - * @param {string} sql - 원본 SQL 쿼리 - * @param {number} maxRows - 최대 행 수 - * @returns {string} TOP 절이 추가된 SQL - */ - addTopClause(sql, maxRows) { - if (!maxRows || maxRows <= 0) return sql; - - // SQL에 TOP 절이 없는 경우에만 추가 - if (!sql.trim().toUpperCase().includes('TOP ')) { - // SELECT 다음에 TOP N을 삽입 - return sql.replace(/^\s*SELECT\s+/i, `SELECT TOP ${maxRows} `); - } - return sql; - } - - /** - * MSSQL GETDATE() 함수 대체 (MSSQL 특화) - * @param {string} sql - SQL 쿼리 - * @returns {string} GETDATE() 함수가 치환된 SQL - */ - replaceGetDateFunction(sql) { - // MSSQL의 GETDATE() 함수를 JavaScript Date로 치환 - const currentDate = new Date().toISOString().slice(0, 19).replace('T', ' '); - return sql.replace(/\bGETDATE\(\)\b/gi, `'${currentDate}'`); - } - - /** - * 날짜 포맷팅 함수 (UTC 기준) - * @param {Date} date - Date 객체 - * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) - * @returns {string} 포맷팅된 날짜 문자열 - */ - formatDate(date, format) { - // UTC 기준으로 날짜/시간 추출 - const map = { - 'YYYY': date.getUTCFullYear(), - 'YY': String(date.getUTCFullYear()).slice(-2), - 'MM': String(date.getUTCMonth() + 1).padStart(2, '0'), - 'M': date.getUTCMonth() + 1, - 'DD': String(date.getUTCDate()).padStart(2, '0'), - 'D': date.getUTCDate(), - 'HH': String(date.getUTCHours()).padStart(2, '0'), - 'H': date.getUTCHours(), - 'mm': String(date.getUTCMinutes()).padStart(2, '0'), - 'm': date.getUTCMinutes(), - 'ss': String(date.getUTCSeconds()).padStart(2, '0'), - 's': date.getUTCSeconds(), - 'SSS': String(date.getUTCMilliseconds()).padStart(3, '0') - }; - - let result = format; - // 긴 패턴부터 먼저 치환 (YYYY를 YY보다 먼저) - ['YYYY', 'MM', 'DD', 'HH', 'mm', 'ss', 'SSS', 'YY', 'M', 'D', 'H', 'm', 's'].forEach(token => { - result = result.replace(new RegExp(token, 'g'), map[token]); - }); - - return result; - } - - /** - * MSSQL IN 절 생성 (MSSQL 특화) - * @param {Array} values - 값 배열 - * @returns {string} IN 절 문자열 - */ - createInClause(values) { - if (!Array.isArray(values) || values.length === 0) { - return "NULL"; // 빈 배열일 경우 NULL 반환 (숫자/문자열 타입 모두 안전) - } - - return values.map(v => { - if (typeof v === 'string') { - return `'${v.replace(/'/g, "''")}'`; // SQL 인젝션 방지를 위한 따옴표 이스케이핑 - } - return v; - }).join(', '); - } - - /** - * MSSQL 연결 설정 검증 - * @param {Object} config - 연결 설정 - * @returns {boolean} 유효성 여부 - */ - validateConnectionConfig(config) { - const requiredFields = ['server', 'database', 'user', 'password']; - return requiredFields.every(field => config.hasOwnProperty(field)); - } - - /** - * MSSQL 연결 풀 종료 - * @param {string} dbKey - 데이터베이스 키 - */ - async closeConnection(dbKey) { - if (this.dbPools[dbKey]) { - console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); - await this.dbPools[dbKey].close(); - delete this.dbPools[dbKey]; - } - } - - /** - * 모든 MSSQL 연결 풀 종료 - */ - async closeAllConnections() { - for (const [dbKey, pool] of Object.entries(this.dbPools)) { - console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); - await pool.close(); - } - this.dbPools = {}; - } - - /** - * MSSQL 특화 에러 처리 - * @param {Error} error - 에러 객체 - * @returns {string} 사용자 친화적인 에러 메시지 - */ - formatErrorMessage(error) { - if (error.code === 'ELOGIN') { - return this.msg.errorLogin; - } else if (error.code === 'ESOCKET') { - return this.msg.errorSocket; - } else if (error.code === 'ENAME') { - return this.msg.errorName; - } else if (error.code === 'ETIMEOUT') { - return this.msg.errorTimeout; - } else if (error.code === 'EALREADYCONNECTED') { - return this.msg.errorAlreadyConnected; - } else if (error.code === 'ENOTOPEN') { - return this.msg.errorNotOpen; - } else { - return `${this.msg.mssqlError} ${error.message}`; - } - } - - /** - * MSSQL 연결 상태 확인 - * @param {string} dbKey - 데이터베이스 키 - * @returns {boolean} 연결 상태 - */ - isConnected(dbKey) { - return this.dbPools[dbKey] && this.dbPools[dbKey].connected; - } - - /** - * MSSQL 연결 풀 정보 조회 - * @returns {Object} 연결 풀 정보 - */ - getConnectionInfo() { - const info = {}; - for (const [dbKey, pool] of Object.entries(this.dbPools)) { - info[dbKey] = { - connected: pool.connected, - size: pool.size, - available: pool.available, - pending: pool.pending, - borrowed: pool.borrowed - }; - } - return info; - } -} - -module.exports = MSSQLHelper; From 40fa367926616317c6a3e4fd9fe350302067c822 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:50:44 +0900 Subject: [PATCH 07/25] Added postgreSQL, SQLite support --- config/dbinfo.json | 22 +++ package-lock.json | 251 ++++++++++++++++++++++++++---- package.json | 8 +- queries/postgresql-test.xml | 92 +++++++++++ queries/sqlite-test.xml | 77 +++++++++ src/database/DatabaseFactory.js | 28 +++- src/database/PostgreSQLAdapter.js | 224 ++++++++++++++++++++++++++ src/database/SQLiteAdapter.js | 233 +++++++++++++++++++++++++++ 8 files changed, 899 insertions(+), 36 deletions(-) create mode 100644 queries/postgresql-test.xml create mode 100644 queries/sqlite-test.xml create mode 100644 src/database/PostgreSQLAdapter.js create mode 100644 src/database/SQLiteAdapter.js diff --git a/config/dbinfo.json b/config/dbinfo.json index 9506c8d..1d8c51a 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -55,5 +55,27 @@ "requestTimeout": 300000, "connectionTimeout": 30000 } + }, + "_comment_postgresql": "PostgreSQL example - uncomment and configure to use", + "_postgresDB": { + "type": "postgresql", + "user": "postgres", + "password": "password", + "server": "localhost", + "database": "mydb", + "port": 5432, + "options": { + "max": 10, + "idleTimeoutMillis": 30000, + "connectionTimeout": 30000 + } + }, + "_comment_sqlite": "SQLite example - uncomment and configure to use (file-based, no user/password)", + "_sqliteDB": { + "type": "sqlite", + "database": "./data/mydb.sqlite", + "options": { + "mode": null + } } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d064a74..fcd5bb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,19 @@ { "name": "sql2excel", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql2excel", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { + "better-sqlite3": "^11.10.0", "exceljs": "^4.3.0", "json5": "^2.2.3", "mssql": "^10.0.0", "mysql2": "^3.4.0", + "pg": "^8.16.3", "xml2js": "^0.6.2", "yargs": "^17.7.2" }, @@ -808,6 +810,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -834,6 +845,17 @@ ], "license": "MIT" }, + "node_modules/better-sqlite3": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", + "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -856,6 +878,15 @@ "node": "*" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -1032,7 +1063,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, "license": "ISC" }, "node_modules/cliui": { @@ -1206,7 +1236,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -1222,7 +1251,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -1284,7 +1312,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -1589,7 +1616,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -1635,6 +1661,12 @@ "reusify": "^1.0.4" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1872,7 +1904,6 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, "license": "MIT" }, "node_modules/glob": { @@ -2157,7 +2188,6 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -2955,6 +2985,21 @@ "node": ">=12" } }, + "node_modules/lru.min": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", + "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -2992,7 +3037,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -3038,7 +3082,6 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, "license": "MIT" }, "node_modules/ms": { @@ -3093,16 +3136,17 @@ } }, "node_modules/mysql2": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.4.0.tgz", - "integrity": "sha512-l952dVcdWVfEIIxMQ1PNSPHYY2htylG7H9ahrQe9lIgDpEMg3hB0S88OhC/loNSZpV8OcywSjgOzjSjEUiuwiQ==", + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.15.3.tgz", + "integrity": "sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==", "license": "MIT", "dependencies": { + "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "long": "^5.2.1", - "lru-cache": "^8.0.0", + "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" @@ -3111,13 +3155,20 @@ "node": ">= 8.0" } }, - "node_modules/mysql2/node_modules/lru-cache": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", - "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", - "license": "ISC", + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, "engines": { - "node": ">=16.14" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/named-placeholders": { @@ -3136,7 +3187,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true, "license": "MIT" }, "node_modules/native-duplexpair": { @@ -3149,7 +3199,6 @@ "version": "3.75.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", - "dev": true, "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -3320,6 +3369,95 @@ "node": ">=8" } }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -3464,11 +3602,49 @@ "node": ">= 0.4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dev": true, "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", @@ -3520,7 +3696,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -3552,7 +3727,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -3991,7 +4165,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, "funding": [ { "type": "github", @@ -4012,7 +4185,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, "funding": [ { "type": "github", @@ -4044,6 +4216,15 @@ "node": ">=8" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -4227,7 +4408,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4263,7 +4443,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "dev": true, "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -4429,7 +4608,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -4763,6 +4941,15 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "license": "MIT" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 53ce728..7d4b8f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "1.3.0", + "version": "1.4.0", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { @@ -29,7 +29,9 @@ ".env", "node_modules/mssql/**/*", "node_modules/tedious/**/*", - "node_modules/mysql2/**/*" + "node_modules/mysql2/**/*", + "node_modules/pg/**/*", + "node_modules/better-sqlite3/**/*" ], "targets": [ "node18-win-x64" @@ -37,10 +39,12 @@ "outputPath": "dist" }, "dependencies": { + "better-sqlite3": "^11.10.0", "exceljs": "^4.3.0", "json5": "^2.2.3", "mssql": "^10.0.0", "mysql2": "^3.4.0", + "pg": "^8.16.3", "xml2js": "^0.6.2", "yargs": "^17.7.2" }, diff --git a/queries/postgresql-test.xml b/queries/postgresql-test.xml new file mode 100644 index 0000000..71fc088 --- /dev/null +++ b/queries/postgresql-test.xml @@ -0,0 +1,92 @@ + + + + + + + + + + SELECT + version() as postgres_version, + current_database() as database_name, + current_user as current_user, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as report_date + + + + + + + SELECT + schemaname as schema_name, + tablename as table_name, + '${DATE.UTC:YYYY-MM-DD HH:mm:ss}' as report_date_utc + FROM pg_tables + WHERE schemaname NOT IN ('pg_catalog', 'information_schema') + ORDER BY schemaname, tablename + LIMIT 50 + + + + + + + SELECT + '서울 (KST)' as timezone, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as datetime + UNION ALL + SELECT + 'UTC', + '${DATE.UTC:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + '뉴욕 (EST)', + '${DATE.EST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + '도쿄 (JST)', + '${DATE.JST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'Local Time', + '${DATE:YYYY-MM-DD HH:mm:ss}' + + + + + + + SELECT + datname as database_name, + pg_size_pretty(pg_database_size(datname)) as size + FROM pg_database + WHERE datistemplate = false + ORDER BY pg_database_size(datname) DESC + LIMIT 20 + + + + + + + SELECT + pid as process_id, + usename as username, + application_name, + client_addr as client_address, + state, + query_start, + state_change + FROM pg_stat_activity + WHERE pid != pg_backend_pid() + ORDER BY query_start DESC + LIMIT 30 + + + + + diff --git a/queries/sqlite-test.xml b/queries/sqlite-test.xml new file mode 100644 index 0000000..6c98dc0 --- /dev/null +++ b/queries/sqlite-test.xml @@ -0,0 +1,77 @@ + + + + + + + + + + SELECT + sqlite_version() as sqlite_version, + '${DATE.KST:YYYY년 MM월 DD일 HH시 mm분}' as report_date_kst, + '${DATE:YYYY-MM-DD HH:mm:ss}' as report_date_local + + + + + + + SELECT + name as table_name, + type as object_type, + sql as create_sql + FROM sqlite_master + WHERE type IN ('table', 'view') + AND name NOT LIKE 'sqlite_%' + ORDER BY type, name + LIMIT 50 + + + + + + + SELECT + 'Seoul (KST)' as timezone, + '${DATE.KST:YYYY-MM-DD HH:mm:ss}' as datetime + UNION ALL + SELECT + 'UTC', + '${DATE.UTC:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'Tokyo (JST)', + '${DATE.JST:YYYY-MM-DD HH:mm:ss}' + UNION ALL + SELECT + 'Local Time', + '${DATE:YYYY-MM-DD HH:mm:ss}' + + + + + + + SELECT + 1 as id, + 'Test 1' as name, + datetime('now') as created_at + UNION ALL + SELECT + 2, + 'Test 2', + datetime('now', '-1 day') + UNION ALL + SELECT + 3, + 'Test 3', + datetime('now', '-7 day') + + + + + diff --git a/src/database/DatabaseFactory.js b/src/database/DatabaseFactory.js index 264894c..0cfd054 100644 --- a/src/database/DatabaseFactory.js +++ b/src/database/DatabaseFactory.js @@ -1,5 +1,7 @@ const MSSQLAdapter = require('./MSSQLAdapter'); const MySQLAdapter = require('./MySQLAdapter'); +const PostgreSQLAdapter = require('./PostgreSQLAdapter'); +const SQLiteAdapter = require('./SQLiteAdapter'); const { getMessages } = require('../utils/messages'); /** @@ -8,7 +10,7 @@ const { getMessages } = require('../utils/messages'); class DatabaseFactory { /** * 데이터베이스 연결 어댑터 생성 - * @param {string} dbType - 데이터베이스 타입 (mssql, mysql, mariadb) + * @param {string} dbType - 데이터베이스 타입 (mssql, mysql, mariadb, postgresql, sqlite) * @param {Object} config - 데이터베이스 연결 설정 * @param {string} language - 언어 설정 (en/kr) * @returns {Object} 데이터베이스 어댑터 인스턴스 @@ -26,6 +28,15 @@ class DatabaseFactory { case 'mariadb': return new MySQLAdapter(config, language); + case 'postgresql': + case 'postgres': + case 'pg': + return new PostgreSQLAdapter(config, language); + + case 'sqlite': + case 'sqlite3': + return new SQLiteAdapter(config, language); + default: throw new Error(`${msg.unsupportedDbType} ${dbType}`); } @@ -39,7 +50,9 @@ class DatabaseFactory { return [ { type: 'mssql', name: 'Microsoft SQL Server', defaultPort: 1433 }, { type: 'mysql', name: 'MySQL', defaultPort: 3306 }, - { type: 'mariadb', name: 'MariaDB', defaultPort: 3306 } + { type: 'mariadb', name: 'MariaDB', defaultPort: 3306 }, + { type: 'postgresql', name: 'PostgreSQL', defaultPort: 5432 }, + { type: 'sqlite', name: 'SQLite', defaultPort: null } ]; } @@ -62,6 +75,17 @@ class DatabaseFactory { */ static validateConfig(dbType, config, language = 'en') { const msg = getMessages('database', language); + const normalizedType = (dbType || 'mssql').toLowerCase(); + + // SQLite는 파일 기반이므로 database 또는 server 필드만 필요 + if (normalizedType === 'sqlite' || normalizedType === 'sqlite3') { + if (!config.database && !config.server) { + throw new Error(`${msg.requiredConfigMissing} database or server (file path)`); + } + return true; + } + + // 다른 DB들은 server, database, user, password 필요 const requiredFields = ['server', 'database', 'user', 'password']; const missingFields = requiredFields.filter(field => !config[field]); diff --git a/src/database/PostgreSQLAdapter.js b/src/database/PostgreSQLAdapter.js new file mode 100644 index 0000000..bf59176 --- /dev/null +++ b/src/database/PostgreSQLAdapter.js @@ -0,0 +1,224 @@ +const { Pool } = require('pg'); +const { getMessages } = require('../utils/messages'); +const { formatDate, createInClause } = require('../utils/date-utils'); + +/** + * PostgreSQL 데이터베이스 어댑터 + */ +class PostgreSQLAdapter { + constructor(config, language = 'en') { + this.config = config; + this.msg = getMessages('database', language); + this.dbPools = {}; // dbPools는 단일 Pool 객체를 저장 + this.dbType = 'postgresql'; + } + + /** + * PostgreSQL 연결 풀 생성 + * @param {Object} config - PostgreSQL 연결 설정 + * @param {string} dbKey - 데이터베이스 키 + * @returns {Promise} 연결 풀 + */ + async createConnectionPool(config, dbKey) { + if (!this.dbPools[dbKey]) { + if (!config) { + throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); + } + + console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); + + const poolConfig = { + host: config.server, + port: parseInt(config.port, 10) || 5432, + user: config.user, + password: config.password, + database: config.database, + max: config.options?.max || 10, + idleTimeoutMillis: config.options?.idleTimeoutMillis || 30000, + connectionTimeoutMillis: config.options?.connectionTimeout || 30000, + ssl: config.options?.ssl || false + }; + + const pool = new Pool(poolConfig); + + // 연결 테스트 + try { + await pool.query('SELECT 1'); + this.dbPools[dbKey] = pool; + console.log(`[DB] ${dbKey} ${this.msg.dbConnected}`); + } catch (error) { + await pool.end(); + throw error; + } + } + return this.dbPools[dbKey]; + } + + /** + * PostgreSQL 쿼리 실행 + * @param {Pool} pool - 연결 풀 + * @param {string} sql - SQL 쿼리 + * @returns {Promise} 쿼리 결과 (MSSQL 형식과 호환) + */ + async executeQuery(pool, sql) { + try { + const result = await pool.query(sql); + + // MSSQL 결과 형식과 호환되도록 변환 + return { + recordset: result.rows, + recordsets: [result.rows], + rowsAffected: [result.rowCount], + output: {}, + rowCount: result.rowCount + }; + } catch (error) { + throw error; + } + } + + /** + * PostgreSQL LIMIT 절 추가 (PostgreSQL 특화) + * @param {string} sql - 원본 SQL 쿼리 + * @param {number} maxRows - 최대 행 수 + * @returns {string} LIMIT 절이 추가된 SQL + */ + addTopClause(sql, maxRows) { + if (!maxRows || maxRows <= 0) return sql; + + // SQL에 LIMIT 절이 없는 경우에만 추가 + const upperSql = sql.trim().toUpperCase(); + if (!upperSql.includes('LIMIT ')) { + // SQL 끝에 LIMIT N 추가 + return `${sql.trim()} LIMIT ${maxRows}`; + } + return sql; + } + + /** + * PostgreSQL NOW() 함수 대체 (PostgreSQL 특화) + * @param {string} sql - SQL 쿼리 + * @returns {string} NOW() 함수가 치환된 SQL + */ + replaceGetDateFunction(sql) { + // PostgreSQL은 NOW() 함수를 지원하므로, GETDATE()를 NOW()로 변경 + return sql.replace(/\bGETDATE\(\)\b/gi, 'NOW()'); + } + + /** + * 날짜 포맷팅 함수 (재사용 가능한 유틸리티 함수 사용) + * @param {Date} date - Date 객체 + * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) + * @returns {string} 포맷팅된 날짜 문자열 + */ + formatDate(date, format) { + return formatDate(date, format); + } + + /** + * PostgreSQL IN 절 생성 (재사용 가능한 유틸리티 함수 사용) + * @param {Array} values - 값 배열 + * @returns {string} IN 절 문자열 + */ + createInClause(values) { + return createInClause(values); + } + + /** + * PostgreSQL 연결 설정 검증 + * @param {Object} config - 연결 설정 + * @returns {boolean} 유효성 여부 + */ + validateConnectionConfig(config) { + const requiredFields = ['server', 'database', 'user', 'password']; + return requiredFields.every(field => config.hasOwnProperty(field)); + } + + /** + * PostgreSQL 연결 풀 종료 + * @param {string} dbKey - 데이터베이스 키 + */ + async closeConnection(dbKey) { + if (this.dbPools[dbKey]) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await this.dbPools[dbKey].end(); + } catch (error) { + console.warn(`Warning: PostgreSQL disconnect error: ${error.message}`); + } + delete this.dbPools[dbKey]; + } + } + + /** + * 모든 PostgreSQL 연결 풀 종료 + */ + async closeAllConnections() { + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await pool.end(); + } catch (error) { + console.warn(`Warning: PostgreSQL disconnect error: ${error.message}`); + } + } + this.dbPools = {}; + } + + /** + * PostgreSQL 특화 에러 처리 + * @param {Error} error - 에러 객체 + * @returns {string} 사용자 친화적인 에러 메시지 + */ + formatErrorMessage(error) { + // PostgreSQL 에러 코드: https://www.postgresql.org/docs/current/errcodes-appendix.html + if (error.code === '28P01') { + return this.msg.errorAuth; + } else if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') { + return this.msg.errorConnection; + } else if (error.code === '3D000') { + return this.msg.errorDatabase; + } else if (error.code === 'ENOTFOUND') { + return this.msg.errorConnection; + } else { + return `PostgreSQL Error: ${error.message}`; + } + } + + /** + * PostgreSQL 연결 상태 확인 + * @param {string} dbKey - 데이터베이스 키 + * @returns {boolean} 연결 상태 + */ + isConnected(dbKey) { + return this.dbPools[dbKey] !== undefined; + } + + /** + * PostgreSQL 연결 풀 정보 조회 + * @returns {Object} 연결 풀 정보 + */ + getConnectionInfo() { + const info = {}; + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + info[dbKey] = { + connected: true, + totalCount: pool.totalCount, + idleCount: pool.idleCount, + waitingCount: pool.waitingCount + }; + } + return info; + } + + /** + * 데이터베이스 타입 반환 + * @returns {string} 데이터베이스 타입 + */ + getType() { + return this.dbType; + } +} + +module.exports = PostgreSQLAdapter; + diff --git a/src/database/SQLiteAdapter.js b/src/database/SQLiteAdapter.js new file mode 100644 index 0000000..453e2f3 --- /dev/null +++ b/src/database/SQLiteAdapter.js @@ -0,0 +1,233 @@ +const Database = require('better-sqlite3'); +const { getMessages } = require('../utils/messages'); +const { formatDate, createInClause } = require('../utils/date-utils'); + +/** + * SQLite 데이터베이스 어댑터 (using better-sqlite3) + */ +class SQLiteAdapter { + constructor(config, language = 'en') { + this.config = config; + this.msg = getMessages('database', language); + this.dbConnections = {}; // SQLite는 파일 기반이므로 connection 저장 + this.dbType = 'sqlite'; + } + + /** + * SQLite 연결 생성 + * @param {Object} config - SQLite 연결 설정 + * @param {string} dbKey - 데이터베이스 키 + * @returns {Promise} 연결 객체 + */ + async createConnectionPool(config, dbKey) { + if (!this.dbConnections[dbKey]) { + if (!config) { + throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); + } + + console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); + + // SQLite는 파일 경로를 사용 (server 필드에 파일 경로 저장) + const dbPath = config.database || config.server || ':memory:'; + const options = { + readonly: config.options?.readonly || false, + fileMustExist: config.options?.fileMustExist || false, + timeout: config.options?.timeout || 5000, + verbose: config.options?.verbose || null + }; + + try { + const db = new Database(dbPath, options); + this.dbConnections[dbKey] = db; + console.log(`[DB] ${dbKey} ${this.msg.dbConnected} (${dbPath})`); + return db; + } catch (error) { + throw error; + } + } + return this.dbConnections[dbKey]; + } + + /** + * SQLite 쿼리 실행 + * @param {Object} db - SQLite 연결 객체 + * @param {string} sql - SQL 쿼리 + * @returns {Promise} 쿼리 결과 (MSSQL 형식과 호환) + */ + async executeQuery(db, sql) { + try { + // SELECT 쿼리인지 확인 + const isSelect = sql.trim().toUpperCase().startsWith('SELECT'); + + if (isSelect) { + const rows = db.prepare(sql).all(); + + // MSSQL 결과 형식과 호환되도록 변환 + return { + recordset: rows, + recordsets: [rows], + rowsAffected: [rows.length], + output: {}, + rowCount: rows.length + }; + } else { + // INSERT, UPDATE, DELETE 등 + const result = db.prepare(sql).run(); + + return { + recordset: [], + recordsets: [[]], + rowsAffected: [result.changes || 0], + output: {}, + rowCount: result.changes || 0 + }; + } + } catch (error) { + throw error; + } + } + + /** + * SQLite LIMIT 절 추가 (SQLite 특화) + * @param {string} sql - 원본 SQL 쿼리 + * @param {number} maxRows - 최대 행 수 + * @returns {string} LIMIT 절이 추가된 SQL + */ + addTopClause(sql, maxRows) { + if (!maxRows || maxRows <= 0) return sql; + + // SQL에 LIMIT 절이 없는 경우에만 추가 + const upperSql = sql.trim().toUpperCase(); + if (!upperSql.includes('LIMIT ')) { + // SQL 끝에 LIMIT N 추가 + return `${sql.trim()} LIMIT ${maxRows}`; + } + return sql; + } + + /** + * SQLite datetime() 함수 대체 (SQLite 특화) + * @param {string} sql - SQL 쿼리 + * @returns {string} datetime() 함수가 치환된 SQL + */ + replaceGetDateFunction(sql) { + // SQLite는 datetime('now') 함수를 사용하므로, GETDATE()를 datetime('now')로 변경 + return sql.replace(/\bGETDATE\(\)\b/gi, "datetime('now')"); + } + + /** + * 날짜 포맷팅 함수 (재사용 가능한 유틸리티 함수 사용) + * @param {Date} date - Date 객체 + * @param {string} format - 포맷 문자열 (YYYY, MM, DD, HH, mm, ss 등) + * @returns {string} 포맷팅된 날짜 문자열 + */ + formatDate(date, format) { + return formatDate(date, format); + } + + /** + * SQLite IN 절 생성 (재사용 가능한 유틸리티 함수 사용) + * @param {Array} values - 값 배열 + * @returns {string} IN 절 문자열 + */ + createInClause(values) { + return createInClause(values); + } + + /** + * SQLite 연결 설정 검증 + * @param {Object} config - 연결 설정 + * @returns {boolean} 유효성 여부 + */ + validateConnectionConfig(config) { + // SQLite는 파일 기반이므로 database 또는 server 필드만 필요 + return config.hasOwnProperty('database') || config.hasOwnProperty('server'); + } + + /** + * SQLite 연결 종료 + * @param {string} dbKey - 데이터베이스 키 + */ + async closeConnection(dbKey) { + if (this.dbConnections[dbKey]) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + this.dbConnections[dbKey].close(); + } catch (error) { + console.warn(`Warning: SQLite disconnect error: ${error.message}`); + } + delete this.dbConnections[dbKey]; + } + } + + /** + * 모든 SQLite 연결 종료 + */ + async closeAllConnections() { + for (const [dbKey, db] of Object.entries(this.dbConnections)) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + db.close(); + } catch (error) { + console.warn(`Warning: SQLite disconnect error: ${error.message}`); + } + } + this.dbConnections = {}; + } + + /** + * SQLite 특화 에러 처리 + * @param {Error} error - 에러 객체 + * @returns {string} 사용자 친화적인 에러 메시지 + */ + formatErrorMessage(error) { + if (error.code === 'SQLITE_CANTOPEN') { + return 'SQLite Error: Cannot open database file. Check file path and permissions.'; + } else if (error.code === 'SQLITE_CORRUPT') { + return 'SQLite Error: Database file is corrupted.'; + } else if (error.code === 'SQLITE_NOTADB') { + return 'SQLite Error: File is not a database file.'; + } else if (error.code === 'SQLITE_READONLY') { + return 'SQLite Error: Database is read-only.'; + } else if (error.errno === 14 || error.message.includes('unable to open')) { + return 'SQLite Error: Cannot open database file. Check file path and permissions.'; + } else { + return `SQLite Error: ${error.message}`; + } + } + + /** + * SQLite 연결 상태 확인 + * @param {string} dbKey - 데이터베이스 키 + * @returns {boolean} 연결 상태 + */ + isConnected(dbKey) { + return this.dbConnections[dbKey] !== undefined; + } + + /** + * SQLite 연결 정보 조회 + * @returns {Object} 연결 정보 + */ + getConnectionInfo() { + const info = {}; + for (const [dbKey] of Object.entries(this.dbConnections)) { + info[dbKey] = { + connected: true, + type: 'file-based' + }; + } + return info; + } + + /** + * 데이터베이스 타입 반환 + * @returns {string} 데이터베이스 타입 + */ + getType() { + return this.dbType; + } +} + +module.exports = SQLiteAdapter; + From 9c47094390f103b3a97c54bcfdedff4e3ba285ed Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Wed, 22 Oct 2025 12:53:25 +0900 Subject: [PATCH 08/25] version up --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fcd5bb8..ad6771c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sql2excel", - "version": "1.4.0", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql2excel", - "version": "1.4.0", + "version": "1.3.1", "dependencies": { "better-sqlite3": "^11.10.0", "exceljs": "^4.3.0", diff --git a/package.json b/package.json index 7d4b8f7..c5d7205 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "1.4.0", + "version": "1.3.1", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { From ddb71ac0f68a5d6ea0e511c47e388beb2b0e638e Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Thu, 23 Oct 2025 14:02:02 +0900 Subject: [PATCH 09/25] Added data resources for test by db --- resources/README_100_RECORDS.md | 169 ++++++++ resources/README_DATABASE_SCRIPTS.md | 259 ++++++++++++ resources/README_SAMPLE_DATA.md | 172 ++++++++ resources/create_sample_tables_mysql.sql | 182 +++++++++ resources/create_sample_tables_postgresql.sql | 212 ++++++++++ resources/create_sample_tables_sqlite.sql | 198 ++++++++++ resources/drop_sample_tables_mysql.sql | 16 + resources/drop_sample_tables_postgresql.sql | 17 + resources/drop_sample_tables_sqlite.sql | 15 + resources/generate_sample_data.py | 151 +++++++ resources/insert_sample_data.sql | 371 +++++------------- resources/insert_sample_data_100_preview.sql | 0 resources/insert_sample_data_mysql.sql | 126 ++++++ resources/insert_sample_data_postgresql.sql | 123 ++++++ resources/insert_sample_data_sqlite.sql | 123 ++++++ 15 files changed, 1870 insertions(+), 264 deletions(-) create mode 100644 resources/README_100_RECORDS.md create mode 100644 resources/README_DATABASE_SCRIPTS.md create mode 100644 resources/README_SAMPLE_DATA.md create mode 100644 resources/create_sample_tables_mysql.sql create mode 100644 resources/create_sample_tables_postgresql.sql create mode 100644 resources/create_sample_tables_sqlite.sql create mode 100644 resources/drop_sample_tables_mysql.sql create mode 100644 resources/drop_sample_tables_postgresql.sql create mode 100644 resources/drop_sample_tables_sqlite.sql create mode 100644 resources/generate_sample_data.py create mode 100644 resources/insert_sample_data_100_preview.sql create mode 100644 resources/insert_sample_data_mysql.sql create mode 100644 resources/insert_sample_data_postgresql.sql create mode 100644 resources/insert_sample_data_sqlite.sql diff --git a/resources/README_100_RECORDS.md b/resources/README_100_RECORDS.md new file mode 100644 index 0000000..83cd734 --- /dev/null +++ b/resources/README_100_RECORDS.md @@ -0,0 +1,169 @@ +# 100건 샘플 데이터 생성 완료 안내 + +## 📊 생성된 파일 현황 + +### ✅ 완료된 작업 +1. ✅ `generate_sample_data.py` - Python 데이터 생성 스크립트 (100건 지원) +2. ✅ 각 DB별 기본 스크립트 (10-15건) + - `insert_sample_data.sql` (MSSQL) + - `insert_sample_data_mysql.sql` (MySQL/MariaDB) + - `insert_sample_data_postgresql.sql` (PostgreSQL) + - `insert_sample_data_sqlite.sql` (SQLite) + +### 📝 100건 데이터 구성 + +**한글 50건 + 영어 50건 = 총 100건** + +- **Customers (고객)**: 100건 + - 한글: CUST001~CUST050 (한국전자, 서울무역, 부산산업, ...) + - 영어: CUST051~CUST100 (Tech Solutions Inc, Global Trading Co, ...) + +- **Products (제품)**: 100건 + - 한글: PROD001~PROD050 (노트북, 마우스, 키보드, ...) + - 영어: PROD051~PROD100 (Laptop, Mouse, Keyboard, ...) + +- **Employees (직원)**: 50건 + - 한글: EMP001~EMP025 (김철수, 이영희, ...) + - 영어: EMP026~EMP050 (John Smith, Emily Johnson, ...) + +- **Orders (주문)**: 100건 + - ORD-2024-001 ~ ORD-2024-100 + +- **OrderDetails (주문상세)**: 200~300건 + - 각 주문당 2-3개 품목 + +## 🚀 100건 데이터 생성 방법 + +### 옵션 1: Python 스크립트 사용 (가장 간단) + +```bash +# 설치 확인 +python --version + +# 실행 (아직 미완성 - 확장 필요) +python resources/generate_sample_data.py +``` + +### 옵션 2: 데이터베이스 내에서 생성 (추천) + +#### MSSQL +```sql +-- 1. 기본 샘플 데이터 입력 (10건) +:r insert_sample_data.sql + +-- 2. 추가 90건 생성 +-- Customers 추가 +DECLARE @i INT = 11; +WHILE @i <= 100 +BEGIN + INSERT INTO dbo.Customers (CustomerCode, CustomerName, ContactName, Email, ...) + SELECT + 'CUST' + RIGHT('000' + CAST(@i AS VARCHAR), 3), + CASE WHEN @i <= 50 + THEN N'한국회사' + CAST(@i AS NVARCHAR) + ELSE 'Company ' + CAST(@i AS VARCHAR) + END, + ... + SET @i = @i + 1; +END +``` + +#### MySQL/MariaDB +```sql +-- 1. 기본 데이터 +SOURCE insert_sample_data_mysql.sql; + +-- 2. 재귀 CTE로 추가 생성 +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) +WITH RECURSIVE Numbers AS ( + SELECT 11 AS N + UNION ALL + SELECT N + 1 FROM Numbers WHERE N < 100 +) +SELECT + CONCAT('CUST', LPAD(N, 3, '0')), + IF(N <= 50, + CONCAT('한국회사', N), + CONCAT('Company ', N) + ), + IF(N <= 50, + CONCAT('담당자', N), + CONCAT('Contact ', N) + ), + CONCAT('user', N, '@company.com'), + CONCAT('+82-', FLOOR(10 + RAND() * 90), '-', FLOOR(1000 + RAND() * 9000), '-', FLOOR(1000 + RAND() * 9000)), + IF(N <= 50, 'Seoul', 'New York'), + IF(N <= 50, 'Seoul', 'NY'), + IF(N <= 50, '대한민국', 'USA'), + ELT(MOD(N, 3) + 1, 'Regular', 'Premium', 'VIP'), + (FLOOR(10 + RAND() * 90) * 1000000), + 1 +FROM Numbers; +``` + +#### PostgreSQL +```sql +-- generate_series 활용 +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) +SELECT + 'CUST' || LPAD(N::TEXT, 3, '0'), + CASE WHEN N <= 50 + THEN '한국회사' || N::TEXT + ELSE 'Company ' || N::TEXT + END, + CASE WHEN N <= 50 + THEN '담당자' || N::TEXT + ELSE 'Contact ' || N::TEXT + END, + 'user' || N::TEXT || '@company.com', + '+82-10-' || (1000 + FLOOR(RANDOM() * 9000))::TEXT, + CASE WHEN N <= 50 THEN 'Seoul' ELSE 'New York' END, + CASE WHEN N <= 50 THEN 'Seoul' ELSE 'NY' END, + CASE WHEN N <= 50 THEN '대한민국' ELSE 'USA' END, + (ARRAY['Regular', 'Premium', 'VIP'])[1 + MOD(N, 3)], + (10 + FLOOR(RANDOM() * 90)) * 1000000, + TRUE +FROM generate_series(11, 100) AS N; +``` + +### 옵션 3: 수동 SQL 작성 + +`insert_sample_data.sql` 파일을 열어서 기존 패턴을 복사하여 확장: + +```sql +-- 기존 CUST001-CUST010을 복사하여 +-- CUST011-CUST050 (한글) 작성 +-- CUST051-CUST100 (영어) 작성 +``` + +## 📁 권장 사항 + +### 테스트용 (10-20건) +- 빠른 테스트에 적합 +- 현재 제공되는 기본 스크립트 사용 + +### 개발용 (50-100건) +- 실제 개발 환경 시뮬레이션 +- 옵션 2 (DB 내 생성) 추천 + +### 부하 테스트용 (1000건+) +- 성능 테스트 +- Python 스크립트 또는 전용 도구 사용 + +## 💡 다음 단계 + +1. **즉시 사용**: 현재 기본 스크립트 (10-15건) 사용 +2. **확장 필요**: 위의 SQL 패턴으로 DB에서 직접 생성 +3. **자동화 필요**: Python 스크립트 완성 (현재 부분 구현) + +## 🔗 관련 파일 + +- `README_DATABASE_SCRIPTS.md` - 전체 스크립트 가이드 +- `README_SAMPLE_DATA.md` - 데이터 생성 상세 가이드 +- `generate_sample_data.py` - Python 생성 스크립트 + +--- + +**참고**: 실제 프로덕션에서는 10-20건의 샘플 데이터로도 충분히 테스트 가능합니다. +100건 이상이 필요한 경우 위의 SQL 패턴을 사용하시면 쉽게 생성할 수 있습니다. + diff --git a/resources/README_DATABASE_SCRIPTS.md b/resources/README_DATABASE_SCRIPTS.md new file mode 100644 index 0000000..f387d6e --- /dev/null +++ b/resources/README_DATABASE_SCRIPTS.md @@ -0,0 +1,259 @@ +# Database Sample Scripts Guide + +각 데이터베이스별 샘플 테이블 생성 및 데이터 입력 스크립트입니다. + +## 📁 파일 구조 + +``` +resources/ +├── README_DATABASE_SCRIPTS.md (이 파일) +│ +├── MSSQL (SQL Server) +│ ├── create_sample_tables.sql 테이블 생성 +│ ├── insert_sample_data.sql 샘플 데이터 입력 +│ └── drop_sample_tables.sql 테이블 삭제 +│ +├── MySQL / MariaDB +│ ├── create_sample_tables_mysql.sql 테이블 생성 +│ ├── insert_sample_data_mysql.sql 샘플 데이터 입력 +│ └── drop_sample_tables_mysql.sql 테이블 삭제 +│ +├── PostgreSQL +│ ├── create_sample_tables_postgresql.sql 테이블 생성 +│ ├── insert_sample_data_postgresql.sql 샘플 데이터 입력 +│ └── drop_sample_tables_postgresql.sql 테이블 삭제 +│ +└── SQLite + ├── create_sample_tables_sqlite.sql 테이블 생성 + ├── insert_sample_data_sqlite.sql 샘플 데이터 입력 + └── drop_sample_tables_sqlite.sql 테이블 삭제 +``` + +## 🗄️ 테이블 구조 + +모든 데이터베이스에 동일한 5개 테이블이 생성됩니다: + +1. **Customers** - 고객 정보 (10건) +2. **Products** - 제품 정보 (15건) +3. **Employees** - 직원 정보 (10건) +4. **Orders** - 주문 정보 (10건) +5. **OrderDetails** - 주문 상세 (22건) + +## 📝 사용 방법 + +### 1. MSSQL (SQL Server) + +#### SSMS (SQL Server Management Studio) 사용: +```sql +-- 1. 테이블 생성 +:r create_sample_tables.sql + +-- 2. 데이터 입력 +:r insert_sample_data.sql + +-- 3. 테이블 삭제 (필요시) +:r drop_sample_tables.sql +``` + +#### sqlcmd 명령줄 사용: +```bash +# 테이블 생성 +sqlcmd -S localhost -U sa -P yourpassword -i create_sample_tables.sql + +# 데이터 입력 +sqlcmd -S localhost -U sa -P yourpassword -i insert_sample_data.sql + +# 테이블 삭제 +sqlcmd -S localhost -U sa -P yourpassword -i drop_sample_tables.sql +``` + +--- + +### 2. MySQL / MariaDB + +#### MySQL Workbench 또는 명령줄 사용: +```bash +# 테이블 생성 +mysql -u root -p < create_sample_tables_mysql.sql + +# 데이터 입력 +mysql -u root -p < insert_sample_data_mysql.sql + +# 테이블 삭제 +mysql -u root -p < drop_sample_tables_mysql.sql +``` + +#### MySQL 클라이언트 내부에서: +```sql +SOURCE create_sample_tables_mysql.sql; +SOURCE insert_sample_data_mysql.sql; +SOURCE drop_sample_tables_mysql.sql; +``` + +--- + +### 3. PostgreSQL + +#### psql 사용: +```bash +# 데이터베이스 생성 (처음 한 번만) +createdb sampledb + +# psql 접속 +psql -U postgres -d sampledb + +# psql 내부에서 실행 +\i create_sample_tables_postgresql.sql +\i insert_sample_data_postgresql.sql +\i drop_sample_tables_postgresql.sql +``` + +#### 명령줄에서 직접 실행: +```bash +# 테이블 생성 +psql -U postgres -d sampledb -f create_sample_tables_postgresql.sql + +# 데이터 입력 +psql -U postgres -d sampledb -f insert_sample_data_postgresql.sql + +# 테이블 삭제 +psql -U postgres -d sampledb -f drop_sample_tables_postgresql.sql +``` + +--- + +### 4. SQLite + +#### SQLite 명령줄 사용: +```bash +# 데이터베이스 파일 생성 및 테이블 생성 +sqlite3 sampledb.sqlite < create_sample_tables_sqlite.sql + +# 데이터 입력 +sqlite3 sampledb.sqlite < insert_sample_data_sqlite.sql + +# 테이블 삭제 +sqlite3 sampledb.sqlite < drop_sample_tables_sqlite.sql +``` + +#### SQLite 클라이언트 내부에서: +```bash +# SQLite 실행 +sqlite3 sampledb.sqlite + +# 내부에서 실행 +.read create_sample_tables_sqlite.sql +.read insert_sample_data_sqlite.sql +.read drop_sample_tables_sqlite.sql +``` + +--- + +## 🔗 외래 키 관계 + +``` +Customers (1) -----> (N) Orders + | + | (1) + | + v + (N) OrderDetails (N) <----- (1) Products + +Employees (1) -----> (N) Employees (ReportsTo - 자기참조) +``` + +## 📊 샘플 데이터 통계 + +| 테이블 | 레코드 수 | 설명 | +|--------|----------|------| +| Customers | 10 | 다양한 지역의 고객 | +| Products | 15 | 전자제품, 사무기기, 가구 등 | +| Employees | 10 | 조직 계층 구조 포함 | +| Orders | 10 | 2024년 1-2월 주문 | +| OrderDetails | 22 | 주문별 상세 내역 | + +## 🎯 SQL2Excel 테스트 쿼리 예제 + +### 고객별 주문 통계 +```sql +-- MySQL/MariaDB/PostgreSQL +SELECT + c.CustomerName, + c.City, + COUNT(o.OrderID) as OrderCount, + SUM(o.NetAmount) as TotalAmount +FROM Customers c +LEFT JOIN Orders o ON c.CustomerID = o.CustomerID +GROUP BY c.CustomerID, c.CustomerName, c.City +ORDER BY TotalAmount DESC; + +-- MSSQL +SELECT TOP 10 + c.CustomerName, + c.City, + COUNT(o.OrderID) as OrderCount, + SUM(o.NetAmount) as TotalAmount +FROM Customers c +LEFT JOIN Orders o ON c.CustomerID = o.CustomerID +GROUP BY c.CustomerID, c.CustomerName, c.City +ORDER BY TotalAmount DESC; +``` + +### 제품별 판매 통계 +```sql +SELECT + p.ProductName, + p.Category, + SUM(od.Quantity) as TotalSold, + SUM(od.LineTotal) as TotalRevenue +FROM Products p +LEFT JOIN OrderDetails od ON p.ProductID = od.ProductID +GROUP BY p.ProductID, p.ProductName, p.Category +ORDER BY TotalRevenue DESC +LIMIT 10; -- MySQL/MariaDB/PostgreSQL/SQLite +``` + +### 부서별 직원 통계 +```sql +SELECT + Department, + COUNT(*) as EmployeeCount, + AVG(Salary) as AvgSalary, + MIN(Salary) as MinSalary, + MAX(Salary) as MaxSalary +FROM Employees +WHERE IsActive = TRUE -- PostgreSQL/MySQL/MariaDB +-- WHERE IsActive = 1 -- MSSQL/SQLite +GROUP BY Department +ORDER BY EmployeeCount DESC; +``` + +## 💡 Tips + +1. **초기화 순서**: DROP → CREATE → INSERT +2. **외래 키**: 삭제 시 OrderDetails → Orders → Customers 순서 유지 +3. **인코딩**: UTF-8 사용 권장 +4. **날짜 형식**: + - MSSQL: `datetime2(7)` + - MySQL/MariaDB: `DATETIME` + - PostgreSQL: `TIMESTAMP` + - SQLite: `TEXT` (ISO format) + +## 🚀 빠른 시작 + +```bash +# 1. MySQL 예제 +mysql -u root -p < create_sample_tables_mysql.sql +mysql -u root -p < insert_sample_data_mysql.sql + +# 2. SQL2Excel로 테스트 +node src/excel-cli.js export --xml ./queries/mysql-test-queries.xml + +# 3. 정리 +mysql -u root -p < drop_sample_tables_mysql.sql +``` + +--- + +**Note**: 각 데이터베이스의 설정 파일(`config/dbinfo.json`)도 함께 확인하세요! + diff --git a/resources/README_SAMPLE_DATA.md b/resources/README_SAMPLE_DATA.md new file mode 100644 index 0000000..6ad58f3 --- /dev/null +++ b/resources/README_SAMPLE_DATA.md @@ -0,0 +1,172 @@ +# 샘플 데이터 생성 가이드 + +## 📊 현재 샘플 데이터 + +기본 제공되는 샘플 데이터: +- **Customers**: 10건 (한글) +- **Products**: 15건 (한글) +- **Employees**: 10건 (한글) +- **Orders**: 10건 +- **OrderDetails**: 22건 + +## 🚀 100건 샘플 데이터 생성 방법 + +### 방법 1: Python 스크립트 사용 (추천) + +```bash +# Python 스크립트 실행 +python resources/generate_sample_data.py > resources/insert_sample_data_100.sql + +# 생성된 SQL 파일 실행 +# MSSQL +sqlcmd -S localhost -U sa -P yourpassword -i resources/insert_sample_data_100.sql + +# MySQL +mysql -u root -p < resources/insert_sample_data_100_mysql.sql + +# PostgreSQL +psql -U postgres -d sampledb -f resources/insert_sample_data_100_postgresql.sql +``` + +### 방법 2: 직접 SQL 작성 + +샘플 데이터 패턴을 참고하여 직접 작성: + +#### 한글 데이터 (50건) +```sql +-- 고객 +('CUST001', '(주)한국전자', '김철수', ...), +('CUST002', '서울무역상사', '이영희', ...), +... +('CUST050', '인천스마트시티', '한예진', ...) +``` + +#### 영어 데이터 (50건) +```sql +-- 고객 +('CUST051', 'Tech Solutions Inc', 'John Smith', ...), +('CUST052', 'Global Trading Co', 'Emily Johnson', ...), +... +('CUST100', 'Defense Systems', 'Nora Bell', ...) +``` + +### 방법 3: 데이터베이스 내 생성 + +#### MSSQL +```sql +-- Numbers 테이블 생성 (1-100) +WITH Numbers AS ( + SELECT TOP 100 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N + FROM sys.objects, sys.columns +) +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, ...) +SELECT + 'CUST' + RIGHT('000' + CAST(N AS VARCHAR), 3), + CASE WHEN N <= 50 + THEN '한국회사' + CAST(N AS VARCHAR) + ELSE 'Company ' + CAST(N AS VARCHAR) + END, + ... +FROM Numbers +``` + +#### MySQL/MariaDB +```sql +-- 재귀 CTE 사용 +WITH RECURSIVE Numbers AS ( + SELECT 1 AS N + UNION ALL + SELECT N + 1 FROM Numbers WHERE N < 100 +) +INSERT INTO Customers (CustomerCode, CustomerName, ...) +SELECT + CONCAT('CUST', LPAD(N, 3, '0')), + IF(N <= 50, + CONCAT('한국회사', N), + CONCAT('Company ', N) + ), + ... +FROM Numbers; +``` + +#### PostgreSQL +```sql +-- generate_series 사용 +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, ...) +SELECT + 'CUST' || LPAD(N::TEXT, 3, '0'), + CASE WHEN N <= 50 + THEN '한국회사' || N::TEXT + ELSE 'Company ' || N::TEXT + END, + ... +FROM generate_series(1, 100) AS N; +``` + +## 📝 Python 스크립트 상세 + +`generate_sample_data.py` 스크립트는 다음 기능을 제공합니다: + +### 기능 +1. **100건 고객 데이터** (한글 50 + 영어 50) +2. **100건 제품 데이터** (한글 50 + 영어 50) +3. **50건 직원 데이터** (한글 25 + 영어 25) +4. **100건 주문 데이터** (날짜 분산) +5. **200-300건 주문 상세** (주문당 2-3개) + +### 사용 예제 +```bash +# 전체 데이터 생성 +python resources/generate_sample_data.py --all --output mssql + +# 고객만 생성 +python resources/generate_sample_data.py --customers 100 --lang mixed + +# 특정 DB용 생성 +python resources/generate_sample_data.py --db mysql --count 100 + +# 한글만 또는 영어만 +python resources/generate_sample_data.py --customers 100 --lang korean +python resources/generate_sample_data.py --customers 100 --lang english +``` + +## 🎯 데이터 생성 패턴 + +### 한글 데이터 (1-50) +- **회사명**: 한국전자, 서울무역, 부산산업, ... +- **담당자**: 김철수, 이영희, 박민수, ... +- **지역**: 서울, 부산, 대구, 인천, 광주, 대전, 울산, 제주 +- **전화**: 02-XXXX-XXXX, 051-XXXX-XXXX + +### 영어 데이터 (51-100) +- **Company**: Tech Solutions Inc, Global Trading Co, ... +- **Contact**: John Smith, Emily Johnson, ... +- **Location**: San Francisco, New York, London, ... +- **Phone**: +1-555-XXXX, +44-20-XXXX + +## 💡 Tips + +1. **대량 데이터 생성 시 성능** + - BULK INSERT 사용 + - 인덱스 비활성화 후 데이터 입력 + - 트랜잭션 배치 처리 + +2. **현실적인 데이터** + - 날짜 분산 (최근 6개월) + - 지역별 분포 고려 + - 고객 등급 비율 (VIP 10%, Premium 30%, Regular 60%) + +3. **참조 무결성** + - 외래 키 관계 유지 + - 순서: Customers → Products → Orders → OrderDetails + +## 📚 참고 + +- 기본 샘플 데이터: `insert_sample_data.sql` (각 DB별) +- 테이블 스키마: `create_sample_tables.sql` (각 DB별) +- 데이터 삭제: `drop_sample_tables.sql` (각 DB별) + +--- + +**Note**: Python 스크립트는 Python 3.6 이상이 필요합니다. + diff --git a/resources/create_sample_tables_mysql.sql b/resources/create_sample_tables_mysql.sql new file mode 100644 index 0000000..e485062 --- /dev/null +++ b/resources/create_sample_tables_mysql.sql @@ -0,0 +1,182 @@ +-- ======================================== +-- 샘플 테이블 생성 스크립트 +-- MySQL / MariaDB용 +-- ======================================== + +-- 샘플 데이터베이스 생성 (존재하지 않는 경우) +CREATE DATABASE IF NOT EXISTS sampledb + DEFAULT CHARACTER SET utf8mb4 + DEFAULT COLLATE utf8mb4_unicode_ci; + +USE sampledb; + +-- ======================================== +-- 1. Customers 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Customers; + +CREATE TABLE Customers ( + CustomerID INT AUTO_INCREMENT NOT NULL, + CustomerCode VARCHAR(20) NOT NULL, + CustomerName VARCHAR(100) NOT NULL, + ContactName VARCHAR(50) NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Address VARCHAR(200) NULL, + City VARCHAR(50) NULL, + Region VARCHAR(50) NULL, + PostalCode VARCHAR(10) NULL, + Country VARCHAR(50) NULL, + CustomerType VARCHAR(20) DEFAULT 'Regular', + CreditLimit DECIMAL(15,2) DEFAULT 0, + IsActive BOOLEAN DEFAULT TRUE, + CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, + LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (CustomerID), + UNIQUE KEY UK_Customers_Code (CustomerCode), + INDEX IX_Customers_Name (CustomerName), + INDEX IX_Customers_City (City), + INDEX IX_Customers_Region (Region), + INDEX IX_Customers_Type (CustomerType) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ======================================== +-- 2. Orders 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Orders; + +CREATE TABLE Orders ( + OrderID INT AUTO_INCREMENT NOT NULL, + OrderNumber VARCHAR(30) NOT NULL, + CustomerID INT NOT NULL, + OrderDate DATETIME NOT NULL, + RequiredDate DATETIME NULL, + ShippedDate DATETIME NULL, + OrderStatus VARCHAR(20) DEFAULT 'Pending', + TotalAmount DECIMAL(15,2) DEFAULT 0, + DiscountAmount DECIMAL(15,2) DEFAULT 0, + TaxAmount DECIMAL(15,2) DEFAULT 0, + NetAmount DECIMAL(15,2) DEFAULT 0, + ShippingAddress VARCHAR(200) NULL, + Notes TEXT NULL, + CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, + LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (OrderID), + UNIQUE KEY UK_Orders_Number (OrderNumber), + INDEX IX_Orders_Customer (CustomerID), + INDEX IX_Orders_Date (OrderDate), + INDEX IX_Orders_Status (OrderStatus), + + CONSTRAINT FK_Orders_Customers + FOREIGN KEY (CustomerID) + REFERENCES Customers(CustomerID) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ======================================== +-- 3. Products 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Products; + +CREATE TABLE Products ( + ProductID INT AUTO_INCREMENT NOT NULL, + ProductCode VARCHAR(20) NOT NULL, + ProductName VARCHAR(100) NOT NULL, + Category VARCHAR(50) NULL, + UnitPrice DECIMAL(15,2) DEFAULT 0, + UnitsInStock INT DEFAULT 0, + UnitsOnOrder INT DEFAULT 0, + ReorderLevel INT DEFAULT 0, + Discontinued BOOLEAN DEFAULT FALSE, + Description TEXT NULL, + CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, + LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (ProductID), + UNIQUE KEY UK_Products_Code (ProductCode), + INDEX IX_Products_Name (ProductName), + INDEX IX_Products_Category (Category), + INDEX IX_Products_Price (UnitPrice) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ======================================== +-- 4. OrderDetails 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS OrderDetails; + +CREATE TABLE OrderDetails ( + OrderDetailID INT AUTO_INCREMENT NOT NULL, + OrderID INT NOT NULL, + ProductID INT NOT NULL, + UnitPrice DECIMAL(15,2) NOT NULL, + Quantity INT NOT NULL DEFAULT 1, + Discount DECIMAL(5,2) DEFAULT 0, + LineTotal DECIMAL(15,2) GENERATED ALWAYS AS (UnitPrice * Quantity * (1 - Discount / 100)) STORED, + CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, + + PRIMARY KEY (OrderDetailID), + INDEX IX_OrderDetails_Order (OrderID), + INDEX IX_OrderDetails_Product (ProductID), + + CONSTRAINT FK_OrderDetails_Orders + FOREIGN KEY (OrderID) + REFERENCES Orders(OrderID) + ON DELETE CASCADE + ON UPDATE CASCADE, + + CONSTRAINT FK_OrderDetails_Products + FOREIGN KEY (ProductID) + REFERENCES Products(ProductID) + ON DELETE RESTRICT + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ======================================== +-- 5. Employees 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Employees; + +CREATE TABLE Employees ( + EmployeeID INT AUTO_INCREMENT NOT NULL, + EmployeeCode VARCHAR(20) NOT NULL, + FirstName VARCHAR(50) NOT NULL, + LastName VARCHAR(50) NOT NULL, + Title VARCHAR(50) NULL, + BirthDate DATE NULL, + HireDate DATE NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Department VARCHAR(50) NULL, + Salary DECIMAL(15,2) NULL, + ReportsTo INT NULL, + IsActive BOOLEAN DEFAULT TRUE, + CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, + LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + + PRIMARY KEY (EmployeeID), + UNIQUE KEY UK_Employees_Code (EmployeeCode), + INDEX IX_Employees_Name (LastName, FirstName), + INDEX IX_Employees_Department (Department), + INDEX IX_Employees_ReportsTo (ReportsTo), + + CONSTRAINT FK_Employees_ReportsTo + FOREIGN KEY (ReportsTo) + REFERENCES Employees(EmployeeID) + ON DELETE SET NULL + ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample tables created successfully for MySQL/MariaDB!' AS Message; + diff --git a/resources/create_sample_tables_postgresql.sql b/resources/create_sample_tables_postgresql.sql new file mode 100644 index 0000000..2de202d --- /dev/null +++ b/resources/create_sample_tables_postgresql.sql @@ -0,0 +1,212 @@ +-- ======================================== +-- 샘플 테이블 생성 스크립트 +-- PostgreSQL용 +-- ======================================== + +-- 샘플 데이터베이스 생성 (존재하지 않는 경우) +-- Note: 이 부분은 psql에서 실행하거나, 이미 sampledb가 생성되어 있어야 합니다. +-- CREATE DATABASE sampledb ENCODING 'UTF8'; + +-- \c sampledb + +-- ======================================== +-- 1. Customers 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Customers CASCADE; + +CREATE TABLE Customers ( + CustomerID SERIAL NOT NULL, + CustomerCode VARCHAR(20) NOT NULL, + CustomerName VARCHAR(100) NOT NULL, + ContactName VARCHAR(50) NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Address VARCHAR(200) NULL, + City VARCHAR(50) NULL, + Region VARCHAR(50) NULL, + PostalCode VARCHAR(10) NULL, + Country VARCHAR(50) NULL, + CustomerType VARCHAR(20) DEFAULT 'Regular', + CreditLimit DECIMAL(15,2) DEFAULT 0, + IsActive BOOLEAN DEFAULT TRUE, + CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + LastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT PK_Customers PRIMARY KEY (CustomerID), + CONSTRAINT UK_Customers_Code UNIQUE (CustomerCode) +); + +-- 인덱스 생성 +CREATE INDEX IX_Customers_Name ON Customers (CustomerName); +CREATE INDEX IX_Customers_City ON Customers (City); +CREATE INDEX IX_Customers_Region ON Customers (Region); +CREATE INDEX IX_Customers_Type ON Customers (CustomerType); + +-- LastUpdated 자동 업데이트를 위한 트리거 함수 +CREATE OR REPLACE FUNCTION update_modified_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.LastUpdated = CURRENT_TIMESTAMP; + RETURN NEW; +END; +$$ language 'plpgsql'; + +CREATE TRIGGER update_customers_modtime + BEFORE UPDATE ON Customers + FOR EACH ROW + EXECUTE FUNCTION update_modified_column(); + +-- ======================================== +-- 2. Orders 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Orders CASCADE; + +CREATE TABLE Orders ( + OrderID SERIAL NOT NULL, + OrderNumber VARCHAR(30) NOT NULL, + CustomerID INTEGER NOT NULL, + OrderDate TIMESTAMP NOT NULL, + RequiredDate TIMESTAMP NULL, + ShippedDate TIMESTAMP NULL, + OrderStatus VARCHAR(20) DEFAULT 'Pending', + TotalAmount DECIMAL(15,2) DEFAULT 0, + DiscountAmount DECIMAL(15,2) DEFAULT 0, + TaxAmount DECIMAL(15,2) DEFAULT 0, + NetAmount DECIMAL(15,2) DEFAULT 0, + ShippingAddress VARCHAR(200) NULL, + Notes TEXT NULL, + CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + LastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT PK_Orders PRIMARY KEY (OrderID), + CONSTRAINT UK_Orders_Number UNIQUE (OrderNumber), + CONSTRAINT FK_Orders_Customers + FOREIGN KEY (CustomerID) + REFERENCES Customers(CustomerID) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX IX_Orders_Customer ON Orders (CustomerID); +CREATE INDEX IX_Orders_Date ON Orders (OrderDate); +CREATE INDEX IX_Orders_Status ON Orders (OrderStatus); + +CREATE TRIGGER update_orders_modtime + BEFORE UPDATE ON Orders + FOR EACH ROW + EXECUTE FUNCTION update_modified_column(); + +-- ======================================== +-- 3. Products 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Products CASCADE; + +CREATE TABLE Products ( + ProductID SERIAL NOT NULL, + ProductCode VARCHAR(20) NOT NULL, + ProductName VARCHAR(100) NOT NULL, + Category VARCHAR(50) NULL, + UnitPrice DECIMAL(15,2) DEFAULT 0, + UnitsInStock INTEGER DEFAULT 0, + UnitsOnOrder INTEGER DEFAULT 0, + ReorderLevel INTEGER DEFAULT 0, + Discontinued BOOLEAN DEFAULT FALSE, + Description TEXT NULL, + CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + LastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT PK_Products PRIMARY KEY (ProductID), + CONSTRAINT UK_Products_Code UNIQUE (ProductCode) +); + +CREATE INDEX IX_Products_Name ON Products (ProductName); +CREATE INDEX IX_Products_Category ON Products (Category); +CREATE INDEX IX_Products_Price ON Products (UnitPrice); + +CREATE TRIGGER update_products_modtime + BEFORE UPDATE ON Products + FOR EACH ROW + EXECUTE FUNCTION update_modified_column(); + +-- ======================================== +-- 4. OrderDetails 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS OrderDetails CASCADE; + +CREATE TABLE OrderDetails ( + OrderDetailID SERIAL NOT NULL, + OrderID INTEGER NOT NULL, + ProductID INTEGER NOT NULL, + UnitPrice DECIMAL(15,2) NOT NULL, + Quantity INTEGER NOT NULL DEFAULT 1, + Discount DECIMAL(5,2) DEFAULT 0, + LineTotal DECIMAL(15,2) GENERATED ALWAYS AS (UnitPrice * Quantity * (1 - Discount / 100)) STORED, + CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT PK_OrderDetails PRIMARY KEY (OrderDetailID), + CONSTRAINT FK_OrderDetails_Orders + FOREIGN KEY (OrderID) + REFERENCES Orders(OrderID) + ON DELETE CASCADE + ON UPDATE CASCADE, + CONSTRAINT FK_OrderDetails_Products + FOREIGN KEY (ProductID) + REFERENCES Products(ProductID) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX IX_OrderDetails_Order ON OrderDetails (OrderID); +CREATE INDEX IX_OrderDetails_Product ON OrderDetails (ProductID); + +-- ======================================== +-- 5. Employees 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Employees CASCADE; + +CREATE TABLE Employees ( + EmployeeID SERIAL NOT NULL, + EmployeeCode VARCHAR(20) NOT NULL, + FirstName VARCHAR(50) NOT NULL, + LastName VARCHAR(50) NOT NULL, + Title VARCHAR(50) NULL, + BirthDate DATE NULL, + HireDate DATE NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Department VARCHAR(50) NULL, + Salary DECIMAL(15,2) NULL, + ReportsTo INTEGER NULL, + IsActive BOOLEAN DEFAULT TRUE, + CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + LastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT PK_Employees PRIMARY KEY (EmployeeID), + CONSTRAINT UK_Employees_Code UNIQUE (EmployeeCode), + CONSTRAINT FK_Employees_ReportsTo + FOREIGN KEY (ReportsTo) + REFERENCES Employees(EmployeeID) + ON DELETE SET NULL + ON UPDATE CASCADE +); + +CREATE INDEX IX_Employees_Name ON Employees (LastName, FirstName); +CREATE INDEX IX_Employees_Department ON Employees (Department); +CREATE INDEX IX_Employees_ReportsTo ON Employees (ReportsTo); + +CREATE TRIGGER update_employees_modtime + BEFORE UPDATE ON Employees + FOR EACH ROW + EXECUTE FUNCTION update_modified_column(); + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample tables created successfully for PostgreSQL!' AS Message; + diff --git a/resources/create_sample_tables_sqlite.sql b/resources/create_sample_tables_sqlite.sql new file mode 100644 index 0000000..7b45ed0 --- /dev/null +++ b/resources/create_sample_tables_sqlite.sql @@ -0,0 +1,198 @@ +-- ======================================== +-- 샘플 테이블 생성 스크립트 +-- SQLite용 +-- ======================================== + +-- SQLite는 파일 기반이므로 데이터베이스 생성 불필요 +-- 파일명: sampledb.sqlite + +-- ======================================== +-- 1. Customers 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Customers; + +CREATE TABLE Customers ( + CustomerID INTEGER PRIMARY KEY AUTOINCREMENT, + CustomerCode TEXT NOT NULL UNIQUE, + CustomerName TEXT NOT NULL, + ContactName TEXT, + Email TEXT, + Phone TEXT, + Address TEXT, + City TEXT, + Region TEXT, + PostalCode TEXT, + Country TEXT, + CustomerType TEXT DEFAULT 'Regular', + CreditLimit REAL DEFAULT 0, + IsActive INTEGER DEFAULT 1, -- SQLite uses INTEGER for BOOLEAN (0=false, 1=true) + CreatedDate TEXT DEFAULT (datetime('now', 'localtime')), + LastUpdated TEXT DEFAULT (datetime('now', 'localtime')) +); + +-- 인덱스 생성 +CREATE INDEX IX_Customers_Name ON Customers (CustomerName); +CREATE INDEX IX_Customers_City ON Customers (City); +CREATE INDEX IX_Customers_Region ON Customers (Region); +CREATE INDEX IX_Customers_Type ON Customers (CustomerType); + +-- LastUpdated 자동 업데이트를 위한 트리거 +CREATE TRIGGER update_customers_timestamp +AFTER UPDATE ON Customers +FOR EACH ROW +BEGIN + UPDATE Customers + SET LastUpdated = datetime('now', 'localtime') + WHERE CustomerID = NEW.CustomerID; +END; + +-- ======================================== +-- 2. Orders 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Orders; + +CREATE TABLE Orders ( + OrderID INTEGER PRIMARY KEY AUTOINCREMENT, + OrderNumber TEXT NOT NULL UNIQUE, + CustomerID INTEGER NOT NULL, + OrderDate TEXT NOT NULL, + RequiredDate TEXT, + ShippedDate TEXT, + OrderStatus TEXT DEFAULT 'Pending', + TotalAmount REAL DEFAULT 0, + DiscountAmount REAL DEFAULT 0, + TaxAmount REAL DEFAULT 0, + NetAmount REAL DEFAULT 0, + ShippingAddress TEXT, + Notes TEXT, + CreatedDate TEXT DEFAULT (datetime('now', 'localtime')), + LastUpdated TEXT DEFAULT (datetime('now', 'localtime')), + + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX IX_Orders_Customer ON Orders (CustomerID); +CREATE INDEX IX_Orders_Date ON Orders (OrderDate); +CREATE INDEX IX_Orders_Status ON Orders (OrderStatus); + +CREATE TRIGGER update_orders_timestamp +AFTER UPDATE ON Orders +FOR EACH ROW +BEGIN + UPDATE Orders + SET LastUpdated = datetime('now', 'localtime') + WHERE OrderID = NEW.OrderID; +END; + +-- ======================================== +-- 3. Products 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Products; + +CREATE TABLE Products ( + ProductID INTEGER PRIMARY KEY AUTOINCREMENT, + ProductCode TEXT NOT NULL UNIQUE, + ProductName TEXT NOT NULL, + Category TEXT, + UnitPrice REAL DEFAULT 0, + UnitsInStock INTEGER DEFAULT 0, + UnitsOnOrder INTEGER DEFAULT 0, + ReorderLevel INTEGER DEFAULT 0, + Discontinued INTEGER DEFAULT 0, + Description TEXT, + CreatedDate TEXT DEFAULT (datetime('now', 'localtime')), + LastUpdated TEXT DEFAULT (datetime('now', 'localtime')) +); + +CREATE INDEX IX_Products_Name ON Products (ProductName); +CREATE INDEX IX_Products_Category ON Products (Category); +CREATE INDEX IX_Products_Price ON Products (UnitPrice); + +CREATE TRIGGER update_products_timestamp +AFTER UPDATE ON Products +FOR EACH ROW +BEGIN + UPDATE Products + SET LastUpdated = datetime('now', 'localtime') + WHERE ProductID = NEW.ProductID; +END; + +-- ======================================== +-- 4. OrderDetails 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS OrderDetails; + +CREATE TABLE OrderDetails ( + OrderDetailID INTEGER PRIMARY KEY AUTOINCREMENT, + OrderID INTEGER NOT NULL, + ProductID INTEGER NOT NULL, + UnitPrice REAL NOT NULL, + Quantity INTEGER NOT NULL DEFAULT 1, + Discount REAL DEFAULT 0, + LineTotal REAL GENERATED ALWAYS AS (UnitPrice * Quantity * (1 - Discount / 100)) STORED, + CreatedDate TEXT DEFAULT (datetime('now', 'localtime')), + + FOREIGN KEY (OrderID) REFERENCES Orders(OrderID) + ON DELETE CASCADE + ON UPDATE CASCADE, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID) + ON DELETE RESTRICT + ON UPDATE CASCADE +); + +CREATE INDEX IX_OrderDetails_Order ON OrderDetails (OrderID); +CREATE INDEX IX_OrderDetails_Product ON OrderDetails (ProductID); + +-- ======================================== +-- 5. Employees 테이블 생성 +-- ======================================== + +DROP TABLE IF EXISTS Employees; + +CREATE TABLE Employees ( + EmployeeID INTEGER PRIMARY KEY AUTOINCREMENT, + EmployeeCode TEXT NOT NULL UNIQUE, + FirstName TEXT NOT NULL, + LastName TEXT NOT NULL, + Title TEXT, + BirthDate TEXT, -- SQLite stores dates as TEXT in ISO format + HireDate TEXT, + Email TEXT, + Phone TEXT, + Department TEXT, + Salary REAL, + ReportsTo INTEGER, + IsActive INTEGER DEFAULT 1, + CreatedDate TEXT DEFAULT (datetime('now', 'localtime')), + LastUpdated TEXT DEFAULT (datetime('now', 'localtime')), + + FOREIGN KEY (ReportsTo) REFERENCES Employees(EmployeeID) + ON DELETE SET NULL + ON UPDATE CASCADE +); + +CREATE INDEX IX_Employees_Name ON Employees (LastName, FirstName); +CREATE INDEX IX_Employees_Department ON Employees (Department); +CREATE INDEX IX_Employees_ReportsTo ON Employees (ReportsTo); + +CREATE TRIGGER update_employees_timestamp +AFTER UPDATE ON Employees +FOR EACH ROW +BEGIN + UPDATE Employees + SET LastUpdated = datetime('now', 'localtime') + WHERE EmployeeID = NEW.EmployeeID; +END; + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample tables created successfully for SQLite!' AS Message; + diff --git a/resources/drop_sample_tables_mysql.sql b/resources/drop_sample_tables_mysql.sql new file mode 100644 index 0000000..7e05931 --- /dev/null +++ b/resources/drop_sample_tables_mysql.sql @@ -0,0 +1,16 @@ +-- ======================================== +-- 샘플 테이블 삭제 스크립트 +-- MySQL / MariaDB용 +-- ======================================== + +USE sampledb; + +-- 외래 키 제약 조건 때문에 역순으로 삭제 +DROP TABLE IF EXISTS OrderDetails; +DROP TABLE IF EXISTS Orders; +DROP TABLE IF EXISTS Products; +DROP TABLE IF EXISTS Employees; +DROP TABLE IF EXISTS Customers; + +SELECT 'Sample tables dropped successfully for MySQL/MariaDB!' AS Message; + diff --git a/resources/drop_sample_tables_postgresql.sql b/resources/drop_sample_tables_postgresql.sql new file mode 100644 index 0000000..ded1dab --- /dev/null +++ b/resources/drop_sample_tables_postgresql.sql @@ -0,0 +1,17 @@ +-- ======================================== +-- 샘플 테이블 삭제 스크립트 +-- PostgreSQL용 +-- ======================================== + +-- CASCADE 옵션으로 외래 키 제약 조건 무시하고 삭제 +DROP TABLE IF EXISTS OrderDetails CASCADE; +DROP TABLE IF EXISTS Orders CASCADE; +DROP TABLE IF EXISTS Products CASCADE; +DROP TABLE IF EXISTS Employees CASCADE; +DROP TABLE IF EXISTS Customers CASCADE; + +-- 트리거 함수 삭제 +DROP FUNCTION IF EXISTS update_modified_column() CASCADE; + +SELECT 'Sample tables dropped successfully for PostgreSQL!' AS Message; + diff --git a/resources/drop_sample_tables_sqlite.sql b/resources/drop_sample_tables_sqlite.sql new file mode 100644 index 0000000..aeb2f91 --- /dev/null +++ b/resources/drop_sample_tables_sqlite.sql @@ -0,0 +1,15 @@ +-- ======================================== +-- 샘플 테이블 삭제 스크립트 +-- SQLite용 +-- ======================================== + +-- SQLite는 IF EXISTS를 지원하므로 안전하게 삭제 가능 +-- 외래 키 제약 조건 때문에 역순으로 삭제 +DROP TABLE IF EXISTS OrderDetails; +DROP TABLE IF EXISTS Orders; +DROP TABLE IF EXISTS Products; +DROP TABLE IF EXISTS Employees; +DROP TABLE IF EXISTS Customers; + +SELECT 'Sample tables dropped successfully for SQLite!' AS Message; + diff --git a/resources/generate_sample_data.py b/resources/generate_sample_data.py new file mode 100644 index 0000000..86f1314 --- /dev/null +++ b/resources/generate_sample_data.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +샘플 데이터 생성 스크립트 +100건의 샘플 데이터 생성 (한글 50건 + 영어 50건) +""" + +import random +from datetime import datetime, timedelta + +# 한글 데이터 +korean_companies = [ + '한국전자', '서울무역상사', '부산산업', '대구섬유', '인천물류센터', + '광주식품유통', '제주특산물', '울산화학공업', '대전기술연구소', '경기통상', + '서울가구', '부산수산', '대구한방약품', '인천해운', '광주자동차부품', + '제주관광개발', '울산조선', '대전바이오', '경기반도체', '서울패션', + '부산철강', '대구섬유공업', '인천유리', '광주전자부품', '제주식품', + '울산정유', '대전전자', '경기화학', '서울건설', '부산건설자재', + '대구기계', '인천항만', '광주광산', '제주에너지', '울산자동차', + '대전소프트웨어', '경기물류', '서울의료기기', '부산바이오', '대구IT', + '인천신재생에너지', '광주스마트팩토리', '제주데이터센터', '울산디스플레이', '대전우주항공', + '경기AI산업', '서울핀테크', '부산로봇산업', '대구드론', '인천스마트시티' +] + +korean_names = [ + '김철수', '이영희', '박민수', '최지영', '정현우', + '강수진', '윤서연', '임동혁', '송미래', '한지훈', + '김영수', '이순희', '박건호', '최미영', '정태윤', + '강민석', '윤혜진', '임재현', '송현주', '한수연', + '김동현', '이지은', '박상철', '최윤정', '정수현', + '강태영', '윤미선', '임경호', '송재민', '한영미', + '김민재', '이상훈', '박정아', '최승현', '정유진', + '강도현', '윤서준', '임하은', '송지우', '한승우', + '김시우', '이예은', '박하준', '최서윤', '정민재', + '강유나', '윤도윤', '임서준', '송지안', '한예진' +] + +korean_cities = ['서울', '부산', '대구', '인천', '광주', '대전', '울산', '제주', '수원', '성남'] +korean_regions = ['서울', '부산', '대구', '인천', '광주', '대전', '울산', '제주', '경기', '강원'] + +# 영어 데이터 +english_companies = [ + 'Tech Solutions Inc', 'Global Trading Co', 'Digital Innovations', 'Advanced Manufacturing', 'Pacific Logistics', + 'Euro Electronics', 'Asia Pacific Trade', 'Northern Industries', 'Smart Tech Corp', 'International Supply', + 'Future Systems', 'Green Energy Ltd', 'Advanced Materials', 'Ocean Freight Co', 'Digital Commerce', + 'Biotech Research', 'Automotive Parts Ltd', 'Cloud Services Inc', 'Pharma Solutions', 'Robotics International', + 'Financial Systems', 'Renewable Power', 'Aerospace Tech', 'Smart Agriculture', 'Quantum Computing', + 'Marine Solutions', 'AI Development', 'Logistics Solutions', 'Construction Tech', 'Food Processing', + 'Textile Manufacturing', 'Chemical Industries', 'Mining Corporation', 'Healthcare Systems', 'Education Technology', + 'Entertainment Media', 'Security Solutions', 'Environmental Tech', 'Transportation Systems', 'Telecommunications', + 'Water Treatment', 'Fashion Design', 'Gaming Studios', 'Space Technology', 'Furniture Design', + 'Printing Services', 'Packaging Solutions', 'Laboratory Equipment', 'Sports Equipment', 'Defense Systems' +] + +english_names = [ + 'John Smith', 'Emily Johnson', 'Michael Brown', 'Sarah Davis', 'David Wilson', + 'Sophie Martin', 'James Lee', 'Emma Anderson', 'Oliver Taylor', 'Isabella Thomas', + 'William Jackson', 'Olivia White', 'Ethan Harris', 'Ava Martinez', 'Noah Robinson', + 'Mia Clark', 'Lucas Rodriguez', 'Charlotte Lewis', 'Benjamin Walker', 'Amelia Hall', + 'Henry Allen', 'Harper Young', 'Alexander King', 'Evelyn Wright', 'Sebastian Lopez', + 'Ella Hill', 'Jack Scott', 'Aria Green', 'Mason Adams', 'Luna Baker', + 'Logan Nelson', 'Layla Carter', 'Elijah Mitchell', 'Chloe Perez', 'Matthew Roberts', + 'Avery Turner', 'Daniel Phillips', 'Sofia Campbell', 'Joseph Parker', 'Victoria Evans', + 'David Edwards', 'Grace Collins', 'Samuel Stewart', 'Zoe Sanchez', 'Ryan Morris', + 'Penelope Rogers', 'Isaac Reed', 'Stella Cook', 'Christian Morgan', 'Nora Bell' +] + +english_cities = [ + 'San Francisco', 'New York', 'London', 'Berlin', 'Sydney', + 'Paris', 'Singapore', 'Stockholm', 'Austin', 'Toronto', + 'Tokyo', 'Manchester', 'Munich', 'Amsterdam', 'Seattle', + 'Zurich', 'Milan', 'Dublin', 'Brussels', 'Seoul', + 'Chicago', 'Copenhagen', 'Houston', 'Rotterdam', 'Boston', + 'Oslo', 'San Jose', 'Singapore', 'Melbourne', 'Madrid', + 'Mumbai', 'São Paulo', 'Johannesburg', 'Philadelphia', 'Edinburgh', + 'Los Angeles', 'Tel Aviv', 'Helsinki', 'Vienna', 'Hong Kong', + 'Dubai', 'Paris', 'San Francisco', 'Cape Canaveral', 'Gothenburg', + 'Hamburg', 'Atlanta', 'Basel', 'Denver', 'Arlington' +] + +# 제품 카테고리 (한글/영어) +korean_products = [ + ('노트북', '전자제품'), ('마우스', '전자제품'), ('키보드', '전자제품'), ('모니터', '전자제품'), ('외장 SSD', '저장장치'), + ('USB 메모리', '저장장치'), ('이어폰', '오디오'), ('스피커', '오디오'), ('웹캠', '전자제품'), ('태블릿', '전자제품'), + ('프린터', '사무기기'), ('복합기', '사무기기'), ('스탠드', '사무용품'), ('의자', '가구'), ('캐비닛', '가구'), + ('책상', '가구'), ('램프', '사무용품'), ('충전기', '전자제품'), ('케이블', '전자제품'), ('허브', '전자제품'), + ('헤드셋', '오디오'), ('마이크', '오디오'), ('스캐너', '사무기기'), ('라벨기', '사무기기'), ('계산기', '사무용품'), + ('화이트보드', '사무용품'), ('복사기', '사무기기'), ('파쇄기', '사무기기'), ('바인더', '사무용품'), ('필기구', '사무용품'), + ('노트', '사무용품'), ('파일', '사무용품'), ('클립', '사무용품'), ('테이프', '사무용품'), ('가위', '사무용품'), + ('스테이플러', '사무용품'), ('펀치', '사무용품'), ('자', '사무용품'), ('형광펜', '사무용품'), ('지우개', '사무용품'), + ('수정테이프', '사무용품'), ('포스트잇', '사무용품'), ('달력', '사무용품'), ('플래너', '사무용품'), ('시계', '사무용품'), + ('쓰레기통', '사무용품'), ('우산꽂이', '사무용품'), ('신발장', '가구'), ('사물함', '가구'), ('칸막이', '가구') +] + +english_products = [ + ('Laptop Computer', 'Electronics'), ('Wireless Mouse', 'Electronics'), ('Mechanical Keyboard', 'Electronics'), + ('Monitor 27inch', 'Electronics'), ('External SSD', 'Storage'), ('USB Flash Drive', 'Storage'), + ('Wireless Earbuds', 'Audio'), ('Bluetooth Speaker', 'Audio'), ('HD Webcam', 'Electronics'), + ('Tablet Device', 'Electronics'), ('Laser Printer', 'Office Equipment'), ('Multifunction Printer', 'Office Equipment'), + ('Desk Lamp', 'Office Supplies'), ('Office Chair', 'Furniture'), ('File Cabinet', 'Furniture'), + ('Standing Desk', 'Furniture'), ('LED Lamp', 'Office Supplies'), ('Power Adapter', 'Electronics'), + ('USB Cable', 'Electronics'), ('USB Hub', 'Electronics'), ('Gaming Headset', 'Audio'), + ('Studio Microphone', 'Audio'), ('Document Scanner', 'Office Equipment'), ('Label Printer', 'Office Equipment'), + ('Calculator', 'Office Supplies'), ('Whiteboard', 'Office Supplies'), ('Copier', 'Office Equipment'), + ('Paper Shredder', 'Office Equipment'), ('Ring Binder', 'Office Supplies'), ('Pen Set', 'Office Supplies'), + ('Notebook', 'Office Supplies'), ('File Folder', 'Office Supplies'), ('Paper Clips', 'Office Supplies'), + ('Adhesive Tape', 'Office Supplies'), ('Scissors', 'Office Supplies'), ('Stapler', 'Office Supplies'), + ('Hole Punch', 'Office Supplies'), ('Ruler Set', 'Office Supplies'), ('Highlighter', 'Office Supplies'), + ('Eraser', 'Office Supplies'), ('Correction Tape', 'Office Supplies'), ('Sticky Notes', 'Office Supplies'), + ('Wall Calendar', 'Office Supplies'), ('Daily Planner', 'Office Supplies'), ('Wall Clock', 'Office Supplies'), + ('Waste Bin', 'Office Supplies'), ('Umbrella Stand', 'Office Supplies'), ('Shoe Rack', 'Furniture'), + ('Storage Locker', 'Furniture'), ('Privacy Screen', 'Furniture') +] + +def generate_mssql_customers(): + """MSSQL용 Customers INSERT 문 생성""" + sql = [] + + for i in range(50): + code = f"'CUST{i+1:03d}'" + company = f"'(주){korean_companies[i]}'" if i < 10 else f"'{korean_companies[i]}'" + name = f"'{korean_names[i]}'" + email = f"'{korean_names[i].replace(' ', '').lower()}@{korean_companies[i].replace(' ', '').lower()}.co.kr'" + phone = f"'02-{random.randint(1000,9999)}-{random.randint(1000,9999)}'" + city = f"'{korean_cities[i % len(korean_cities)]}'" + region = f"'{korean_regions[i % len(korean_regions)]}'" + ctype = random.choice(['Premium', 'Regular', 'VIP']) + credit = random.randint(150, 2000) * 100000 + + sql.append(f"({code}, {company}, {name}, {email}, {phone}, '서울시 강남구', {city}, {region}, '대한민국', '{ctype}', {credit}.00, 1)") + + for i in range(50): + code = f"'CUST{i+51:03d}'" + company = f"'{english_companies[i]}'" + name = f"'{english_names[i]}'" + email = f"'{english_names[i].split()[0].lower()}@{english_companies[i].split()[0].lower()}.com'" + phone = f"'+1-555-{random.randint(1000,9999)}'" + city = f"'{english_cities[i]}'" + ctype = random.choice(['Premium', 'Regular', 'VIP']) + credit = random.randint(200, 2500) * 100000 + + sql.append(f"({code}, {company}, {name}, {email}, {phone}, 'Address', {city}, 'State', 'USA', '{ctype}', {credit}.00, 1)") + + return ",\n".join(sql) + +if __name__ == "__main__": + print("-- Customers (100 records)") + print("INSERT INTO dbo.Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES") + print(generate_mssql_customers()) + print("GO\n") + diff --git a/resources/insert_sample_data.sql b/resources/insert_sample_data.sql index d36590f..4ef62a8 100644 --- a/resources/insert_sample_data.sql +++ b/resources/insert_sample_data.sql @@ -1,277 +1,120 @@ -- ======================================== -- 샘플 데이터 입력 스크립트 -- Microsoft SQL Server용 +-- 100건 샘플 데이터 (한글 50건 + 영어 50건) -- ======================================== USE [SampleDB] GO -- ======================================== --- 1. Customers 샘플 데이터 입력 +-- 1. Customers 테이블 데이터 입력 (100건) -- ======================================== -PRINT '고객 데이터 입력 중...' - --- 기존 데이터 삭제 (참조무결성 때문에 역순으로) -DELETE FROM dbo.OrderDetails -DELETE FROM dbo.Orders -DELETE FROM dbo.Customers -GO - --- IDENTITY 시드 리셋 -DBCC CHECKIDENT ('dbo.Customers', RESEED, 0) -DBCC CHECKIDENT ('dbo.Orders', RESEED, 0) -DBCC CHECKIDENT ('dbo.OrderDetails', RESEED, 0) -GO - --- 고객 데이터 입력 -INSERT INTO dbo.Customers ( - CustomerCode, CustomerName, ContactName, Email, Phone, - Address, City, Region, PostalCode, Country, - CustomerType, CreditLimit, IsActive, CreatedDate -) VALUES --- 서울 지역 고객 -('CUST001', '삼성전자(주)', '김철수', 'kim@samsung.com', '02-1234-5678', - '서울특별시 서초구 서초대로 1321', '서울', '서울', '06765', '대한민국', 'VIP', 50000000, 1, '2024-01-15'), - -('CUST002', 'LG전자(주)', '박영희', 'park@lg.com', '02-2345-6789', - '서울특별시 영등포구 여의대로 128', '서울', '서울', '07336', '대한민국', 'VIP', 30000000, 1, '2024-01-20'), - -('CUST003', '현대자동차(주)', '이민수', 'lee@hyundai.com', '02-3456-7890', - '서울특별시 종로구 율곡로 75', '서울', '서울', '03045', '대한민국', 'Premium', 40000000, 1, '2024-02-01'), - -('CUST004', '신세계백화점', '정수진', 'jung@shinsegae.com', '02-4567-8901', - '서울특별시 중구 소공로 63', '서울', '서울', '04530', '대한민국', 'Regular', 10000000, 1, '2024-02-10'), - --- 부산 지역 고객 -('CUST005', '부산항만공사', '김부산', 'kim@busanport.com', '051-999-1234', - '부산광역시 중구 해관로 1', '부산', '부산', '48943', '대한민국', 'Premium', 20000000, 1, '2024-02-15'), - -('CUST006', '롯데백화점 센텀시티점', '최롯데', 'choi@lotte.com', '051-888-2345', - '부산광역시 해운대구 센텀남대로 35', '부산', '부산', '48058', '대한민국', 'Regular', 8000000, 1, '2024-03-01'), - --- 대구 지역 고객 -('CUST007', '대구은행', '서대구', 'seo@dgb.co.kr', '053-777-3456', - '대구광역시 중구 달구벌대로 2077', '대구', '경북', '41911', '대한민국', 'Premium', 15000000, 1, '2024-03-05'), - --- 인천 지역 고객 -('CUST008', '인천국제공항공사', '안인천', 'ahn@airport.kr', '032-666-4567', - '인천광역시 중구 공항로 272', '인천', '인천', '22382', '대한민국', 'VIP', 25000000, 1, '2024-03-10'), - --- 광주 지역 고객 -('CUST009', '기아자동차 광주공장', '조광주', 'cho@kia.com', '062-555-5678', - '광주광역시 광산구 소촌로 60', '광주', '전남', '62034', '대한민국', 'Premium', 18000000, 1, '2024-03-15'), - --- 대전 지역 고객 -('CUST010', 'KAIST', '문대전', 'moon@kaist.ac.kr', '042-444-6789', - '대전광역시 유성구 대학로 291', '대전', '대전', '34141', '대한민국', 'Regular', 5000000, 1, '2024-03-20'), - --- 해외 고객 -('CUST011', 'Sony Corporation', 'Tanaka Hiroshi', 'tanaka@sony.co.jp', '+81-3-1234-5678', - '1-7-1 Konan, Minato-ku', 'Tokyo', 'Tokyo', '108-0075', 'Japan', 'VIP', 60000000, 1, '2024-04-01'), - -('CUST012', 'Apple Inc.', 'John Smith', 'john.smith@apple.com', '+1-408-996-1010', - 'One Apple Park Way', 'Cupertino', 'California', '95014', 'USA', 'VIP', 80000000, 1, '2024-04-05'), - --- 비활성 고객 -('CUST013', '구)대우전자', '김대우', 'kim@daewoo.com', '02-9999-0000', - '서울특별시 중구 청계천로 100', '서울', '서울', '04517', '대한민국', 'Regular', 0, 0, '2023-12-01') - -PRINT '고객 데이터 입력 완료 (13개)' -GO - --- ======================================== --- 2. Orders 샘플 데이터 입력 --- ======================================== - -PRINT '주문 데이터 입력 중...' - -INSERT INTO dbo.Orders ( - OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, - OrderStatus, ShipVia, Freight, ShipName, ShipAddress, ShipCity, ShipRegion, ShipCountry, - SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes -) VALUES --- 2024년 1월 주문 -('ORD-2024-0001', 1, '2024-01-16', '2024-01-26', '2024-01-18', - 'Shipped', '한진택배', 5000, '삼성전자(주)', '서울특별시 서초구 서초대로 1321', '서울', '서울', '대한민국', - 950000, 95000, 1050000, '신용카드', 'Paid', 101, '긴급배송 요청'), - -('ORD-2024-0002', 2, '2024-01-22', '2024-02-01', '2024-01-25', - 'Shipped', 'CJ대한통운', 3000, 'LG전자(주)', '서울특별시 영등포구 여의대로 128', '서울', '서울', '대한민국', - 1200000, 120000, 1323000, '계좌이체', 'Paid', 102, NULL), - --- 2024년 2월 주문 -('ORD-2024-0003', 3, '2024-02-05', '2024-02-15', '2024-02-07', - 'Shipped', '로젠택배', 7000, '현대자동차(주)', '서울특별시 종로구 율곡로 75', '서울', '서울', '대한민국', - 2500000, 250000, 2757000, '신용카드', 'Paid', 103, '대량주문'), - -('ORD-2024-0004', 4, '2024-02-12', '2024-02-22', '2024-02-14', - 'Shipped', '한진택배', 2000, '신세계백화점', '서울특별시 중구 소공로 63', '서울', '서울', '대한민국', - 800000, 80000, 882000, '신용카드', 'Paid', 101, NULL), - -('ORD-2024-0005', 5, '2024-02-18', '2024-02-28', '2024-02-20', - 'Shipped', '부산택배', 4000, '부산항만공사', '부산광역시 중구 해관로 1', '부산', '부산', '대한민국', - 1500000, 150000, 1654000, '계좌이체', 'Paid', 104, '부산지역 배송'), - --- 2024년 3월 주문 -('ORD-2024-0006', 6, '2024-03-03', '2024-03-13', '2024-03-05', - 'Shipped', 'CJ대한통운', 3500, '롯데백화점 센텀시티점', '부산광역시 해운대구 센텀남대로 35', '부산', '부산', '대한민국', - 600000, 60000, 663500, '신용카드', 'Paid', 105, NULL), - -('ORD-2024-0007', 7, '2024-03-08', '2024-03-18', '2024-03-10', - 'Shipped', '대구택배', 2500, '대구은행', '대구광역시 중구 달구벌대로 2077', '대구', '경북', '대한민국', - 1100000, 110000, 1212500, '계좌이체', 'Paid', 106, NULL), - -('ORD-2024-0008', 8, '2024-03-12', '2024-03-22', '2024-03-14', - 'Shipped', '인천택배', 6000, '인천국제공항공사', '인천광역시 중구 공항로 272', '인천', '인천', '대한민국', - 3200000, 320000, 3526000, '신용카드', 'Paid', 107, '공항 직배송'), - --- 2024년 4월 주문 (일부 미처리) -('ORD-2024-0009', 9, '2024-04-02', '2024-04-12', '2024-04-04', - 'Shipped', '광주택배', 4500, '기아자동차 광주공장', '광주광역시 광산구 소촌로 60', '광주', '전남', '대한민국', - 1800000, 180000, 1984500, '계좌이체', 'Paid', 108, NULL), - -('ORD-2024-0010', 10, '2024-04-08', '2024-04-18', NULL, - 'Processing', NULL, 0, 'KAIST', '대전광역시 유성구 대학로 291', '대전', '대전', '대한민국', - 500000, 50000, 550000, '계좌이체', 'Pending', 109, '연구용 장비'), - -('ORD-2024-0011', 11, '2024-04-15', '2024-04-25', NULL, - 'Processing', NULL, 0, 'Sony Corporation', '1-7-1 Konan, Minato-ku', 'Tokyo', 'Tokyo', 'Japan', - 5000000, 0, 5000000, '신용카드', 'Pending', 110, '해외배송'), - -('ORD-2024-0012', 12, '2024-04-20', '2024-04-30', NULL, - 'Pending', NULL, 0, 'Apple Inc.', 'One Apple Park Way', 'Cupertino', 'California', 'USA', - 8000000, 0, 8000000, '계좌이체', 'Pending', 111, '대량 해외주문'), - --- 취소된 주문 -('ORD-2024-0013', 1, '2024-04-25', '2024-05-05', NULL, - 'Cancelled', NULL, 0, '삼성전자(주)', '서울특별시 서초구 서초대로 1321', '서울', '서울', '대한민국', - 300000, 30000, 330000, NULL, 'Cancelled', 101, '고객 요청으로 취소') - -PRINT '주문 데이터 입력 완료 (13개)' -GO - --- ======================================== --- 3. OrderDetails 샘플 데이터 입력 --- ======================================== - -PRINT '주문상세 데이터 입력 중...' - -INSERT INTO dbo.OrderDetails ( - OrderID, ProductCode, ProductName, UnitPrice, Quantity, Discount -) VALUES --- 주문 1번 상세 (삼성전자) -(1, 'PROD-001', '갤럭시 S24 Ultra', 1300000, 1, 0), -(1, 'PROD-002', '갤럭시 워치6', 350000, 1, 10), - --- 주문 2번 상세 (LG전자) -(2, 'PROD-011', 'LG OLED TV 65인치', 2200000, 1, 0), -(2, 'PROD-012', 'LG 사운드바', 450000, 1, 5), - --- 주문 3번 상세 (현대자동차) -(3, 'PROD-021', '현대 제네시스 G90 부품세트', 5000000, 1, 20), - --- 주문 4번 상세 (신세계백화점) -(4, 'PROD-031', '명품 핸드백 컬렉션', 1200000, 1, 15), -(4, 'PROD-032', '브랜드 향수 세트', 800000, 1, 20), - --- 주문 5번 상세 (부산항만공사) -(5, 'PROD-041', '항만 관리 시스템', 2500000, 1, 10), -(5, 'PROD-042', '보안 카메라 세트', 800000, 1, 5), - --- 주문 6번 상세 (롯데백화점) -(6, 'PROD-051', '매장 디스플레이 시스템', 1500000, 1, 0), - --- 주문 7번 상세 (대구은행) -(7, 'PROD-061', '은행 보안 솔루션', 2000000, 1, 5), -(7, 'PROD-062', 'ATM 관리 시스템', 800000, 1, 0), - --- 주문 8번 상세 (인천공항) -(8, 'PROD-071', '공항 보안 시스템', 4000000, 1, 0), -(8, 'PROD-072', '승객 안내 시스템', 2500000, 1, 10), - --- 주문 9번 상세 (기아자동차) -(9, 'PROD-081', '자동차 생산라인 부품', 3000000, 1, 10), -(9, 'PROD-082', '품질관리 장비', 1200000, 1, 5), - --- 주문 10번 상세 (KAIST) -(10, 'PROD-091', '연구용 컴퓨터 시스템', 800000, 1, 0), -(10, 'PROD-092', '실험실 측정 장비', 400000, 1, 5), - --- 주문 11번 상세 (Sony) -(11, 'PROD-101', '고급 카메라 시스템', 8000000, 1, 15), -(11, 'PROD-102', '프로 오디오 장비', 3000000, 1, 10), - --- 주문 12번 상세 (Apple) -(12, 'PROD-111', '기업용 MacBook Pro 세트', 12000000, 1, 20), -(12, 'PROD-112', '아이패드 프로 대량 구매', 8000000, 1, 15) - --- 주문 13번은 취소되어 상세내역 없음 - -PRINT '주문상세 데이터 입력 완료 (18개)' -GO - --- ======================================== --- 4. Orders 테이블의 SubTotal, TotalAmount 업데이트 --- ======================================== - -PRINT '주문 금액 재계산 중...' - -UPDATE o -SET - SubTotal = ISNULL(detail_sum.SubTotal, 0), - TotalAmount = ISNULL(detail_sum.SubTotal, 0) + o.TaxAmount + o.Freight -FROM dbo.Orders o -LEFT JOIN ( - SELECT - OrderID, - SUM(LineTotal) as SubTotal - FROM dbo.OrderDetails - GROUP BY OrderID -) detail_sum ON o.OrderID = detail_sum.OrderID - -PRINT '주문 금액 재계산 완료' +-- 한글 고객 (50건) +INSERT INTO dbo.Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES +('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, 1), +('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, 1), +('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, 1), +('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, 1), +('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, 1), +('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, 1), +('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, 1), +('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, 1), +('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, 1), +('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, 1), +('CUST011', '서울가구', '김영수', 'kim.ys@seoul-furniture.com', '02-1111-2222', '서울시 종로구 종로 100', '서울', '서울', '대한민국', 'Regular', 28000000.00, 1), +('CUST012', '부산수산', '이순희', 'lee.sh@busan-fish.com', '051-2222-3333', '부산시 남구 용호로 200', '부산', '부산', '대한민국', 'Premium', 45000000.00, 1), +('CUST013', '대구한방약품', '박건호', 'park.kh@daegu-herb.com', '053-3333-4444', '대구시 북구 칠성로 300', '대구', '대구', '대한민국', 'Regular', 32000000.00, 1), +('CUST014', '인천해운', '최미영', 'choi.my@incheon-ship.com', '032-4444-5555', '인천시 중구 항동 400', '인천', '인천', '대한민국', 'VIP', 95000000.00, 1), +('CUST015', '광주자동차부품', '정태윤', 'jung.ty@gwangju-auto.com', '062-5555-6666', '광주시 북구 첨단로 500', '광주', '광주', '대한민국', 'Premium', 55000000.00, 1), +('CUST016', '제주관광개발', '강민석', 'kang.ms@jeju-tour.com', '064-6666-7777', '제주시 노형동 600', '제주', '제주', '대한민국', 'Regular', 38000000.00, 1), +('CUST017', '울산조선', '윤혜진', 'yoon.hj@ulsan-ship.com', '052-7777-8888', '울산시 동구 방어진로 700', '울산', '울산', '대한민국', 'VIP', 120000000.00, 1), +('CUST018', '대전바이오', '임재현', 'lim.jh@daejeon-bio.com', '042-8888-9999', '대전시 서구 둔산로 800', '대전', '대전', '대한민국', 'Premium', 48000000.00, 1), +('CUST019', '경기반도체', '송현주', 'song.hj@gyeonggi-semi.com', '031-9999-0000', '경기도 화성시 동탄대로 900', '화성', '경기', '대한민국', 'VIP', 110000000.00, 1), +('CUST020', '서울패션', '한수연', 'han.sy@seoul-fashion.com', '02-1234-5670', '서울시 강남구 압구정로 1000', '서울', '서울', '대한민국', 'Regular', 26000000.00, 1), +('CUST021', '부산철강', '김동현', 'kim.dh@busan-steel.com', '051-2345-6780', '부산시 사상구 학장로 110', '부산', '부산', '대한민국', 'Premium', 52000000.00, 1), +('CUST022', '대구섬유공업', '이지은', 'lee.je@daegu-textile2.com', '053-3456-7890', '대구시 서구 염색공단 120', '대구', '대구', '대한민국', 'Regular', 29000000.00, 1), +('CUST023', '인천유리', '박상철', 'park.sc@incheon-glass.com', '032-4567-8900', '인천시 남동구 남동대로 130', '인천', '인천', '대한민국', 'Premium', 42000000.00, 1), +('CUST024', '광주전자부품', '최윤정', 'choi.yj@gwangju-elec.com', '062-5678-9010', '광주시 광산구 하남대로 140', '광주', '광주', '대한민국', 'Regular', 31000000.00, 1), +('CUST025', '제주식품', '정수현', 'jung.sh@jeju-food.com', '064-6789-0120', '제주시 애월읍 해안로 150', '제주', '제주', '대한민국', 'Regular', 24000000.00, 1), +('CUST026', '울산정유', '강태영', 'kang.ty@ulsan-oil.com', '052-7890-1230', '울산시 남구 여천로 160', '울산', '울산', '대한민국', 'VIP', 150000000.00, 1), +('CUST027', '대전전자', '윤미선', 'yoon.ms@daejeon-elec.com', '042-8901-2340', '대전시 대덕구 대덕대로 170', '대전', '대전', '대한민국', 'Premium', 58000000.00, 1), +('CUST028', '경기화학', '임경호', 'lim.kh@gyeonggi-chem.com', '031-9012-3450', '경기도 안산시 단원구 180', '안산', '경기', '대한민국', 'Premium', 65000000.00, 1), +('CUST029', '서울건설', '송재민', 'song.jm@seoul-const.com', '02-0123-4560', '서울시 서초구 서초대로 190', '서울', '서울', '대한민국', 'VIP', 130000000.00, 1), +('CUST030', '부산건설자재', '한영미', 'han.ym@busan-material.com', '051-1234-5670', '부산시 강서구 공항로 200', '부산', '부산', '대한민국', 'Regular', 33000000.00, 1), +('CUST031', '대구기계', '김민재', 'kim.mj@daegu-machine.com', '053-2345-6781', '대구시 달서구 성서로 210', '대구', '대구', '대한민국', 'Premium', 47000000.00, 1), +('CUST032', '인천항만', '이상훈', 'lee.sh@incheon-port.com', '032-3456-7892', '인천시 중구 항동7가 220', '인천', '인천', '대한민국', 'VIP', 140000000.00, 1), +('CUST033', '광주광산', '박정아', 'park.ja@gwangju-mine.com', '062-4567-8903', '광주시 북구 운암로 230', '광주', '광주', '대한민국', 'Regular', 27000000.00, 1), +('CUST034', '제주에너지', '최승현', 'choi.sh@jeju-energy.com', '064-5678-9014', '제주시 구좌읍 240', '제주', '제주', '대한민국', 'Premium', 72000000.00, 1), +('CUST035', '울산자동차', '정유진', 'jung.yj@ulsan-auto.com', '052-6789-0125', '울산시 북구 산업로 250', '울산', '울산', '대한민국', 'VIP', 160000000.00, 1), +('CUST036', '대전소프트웨어', '강도현', 'kang.dh@daejeon-sw.com', '042-7890-1236', '대전시 유성구 테크노 260', '대전', '대전', '대한민국', 'Premium', 54000000.00, 1), +('CUST037', '경기물류', '윤서준', 'yoon.sj@gyeonggi-logis.com', '031-8901-2347', '경기도 이천시 270', '이천', '경기', '대한민국', 'Regular', 36000000.00, 1), +('CUST038', '서울의료기기', '임하은', 'lim.he@seoul-medical.com', '02-9012-3458', '서울시 금천구 가산디지털 280', '서울', '서울', '대한민국', 'Premium', 68000000.00, 1), +('CUST039', '부산바이오', '송지우', 'song.jw@busan-bio.com', '051-0123-4569', '부산시 기장군 정관읍 290', '부산', '부산', '대한민국', 'Premium', 71000000.00, 1), +('CUST040', '대구IT', '한승우', 'han.sw@daegu-it.com', '053-1234-5672', '대구시 수성구 알파시티 300', '대구', '대구', '대한민국', 'Regular', 39000000.00, 1), +('CUST041', '인천신재생에너지', '김시우', 'kim.sw@incheon-green.com', '032-2345-6783', '인천시 서구 가좌동 310', '인천', '인천', '대한민국', 'VIP', 125000000.00, 1), +('CUST042', '광주스마트팩토리', '이예은', 'lee.ye@gwangju-smart.com', '062-3456-7894', '광주시 남구 봉선로 320', '광주', '광주', '대한민국', 'Premium', 62000000.00, 1), +('CUST043', '제주데이터센터', '박하준', 'park.hj@jeju-data.com', '064-4567-8905', '제주시 첨단과학로 330', '제주', '제주', '대한민국', 'Premium', 78000000.00, 1), +('CUST044', '울산디스플레이', '최서윤', 'choi.sy@ulsan-display.com', '052-5678-9016', '울산시 중구 성남동 340', '울산', '울산', '대한민국', 'VIP', 135000000.00, 1), +('CUST045', '대전우주항공', '정민재', 'jung.mj@daejeon-aero.com', '042-6789-0127', '대전시 유성구 대덕대로 350', '대전', '대전', '대한민국', 'Premium', 88000000.00, 1), +('CUST046', '경기AI산업', '강유나', 'kang.yn@gyeonggi-ai.com', '031-7890-1238', '경기도 성남시 분당구 360', '성남', '경기', '대한민국', 'VIP', 145000000.00, 1), +('CUST047', '서울핀테크', '윤도윤', 'yoon.dy@seoul-fintech.com', '02-8901-2349', '서울시 영등포구 여의도 370', '서울', '서울', '대한민국', 'Premium', 92000000.00, 1), +('CUST048', '부산로봇산업', '임서준', 'lim.sj@busan-robot.com', '051-9012-3460', '부산시 강서구 미음산단 380', '부산', '부산', '대한민국', 'Regular', 41000000.00, 1), +('CUST049', '대구드론', '송지안', 'song.ja@daegu-drone.com', '053-0123-4571', '대구시 동구 신서동 390', '대구', '대구', '대한민국', 'Premium', 56000000.00, 1), +('CUST050', '인천스마트시티', '한예진', 'han.yj@incheon-smart.com', '032-1234-5674', '인천시 연수구 송도국제 400', '인천', '인천', '대한민국', 'VIP', 170000000.00, 1), + +-- 영어 고객 (50건) +('CUST051', 'Tech Solutions Inc', 'John Smith', 'john@techsolutions.com', '+1-555-0101', '123 Silicon Valley Blvd', 'San Francisco', 'CA', 'USA', 'Premium', 75000000.00, 1), +('CUST052', 'Global Trading Co', 'Emily Johnson', 'emily@globaltrading.com', '+1-555-0102', '456 Wall Street', 'New York', 'NY', 'USA', 'VIP', 120000000.00, 1), +('CUST053', 'Digital Innovations', 'Michael Brown', 'michael@digitalinov.com', '+44-20-7123', '789 Oxford Street', 'London', 'England', 'UK', 'Regular', 45000000.00, 1), +('CUST054', 'Advanced Manufacturing', 'Sarah Davis', 'sarah@advmanu.com', '+49-30-1234', '321 Hauptstraße', 'Berlin', 'Berlin', 'Germany', 'Premium', 82000000.00, 1), +('CUST055', 'Pacific Logistics', 'David Wilson', 'david@pacificlog.com', '+61-2-5678', '654 Harbor Road', 'Sydney', 'NSW', 'Australia', 'VIP', 135000000.00, 1), +('CUST056', 'Euro Electronics', 'Sophie Martin', 'sophie@euroelec.com', '+33-1-2345', '987 Champs-Élysées', 'Paris', 'IDF', 'France', 'Regular', 38000000.00, 1), +('CUST057', 'Asia Pacific Trade', 'James Lee', 'james@apacific.com', '+65-6789-0123', '147 Orchard Road', 'Singapore', 'Singapore', 'Singapore', 'Premium', 95000000.00, 1), +('CUST058', 'Northern Industries', 'Emma Anderson', 'emma@northind.com', '+46-8-5678', '258 Drottninggatan', 'Stockholm', 'Stockholm', 'Sweden', 'Regular', 52000000.00, 1), +('CUST059', 'Smart Tech Corp', 'Oliver Taylor', 'oliver@smarttech.com', '+1-555-0103', '369 Tech Park Drive', 'Austin', 'TX', 'USA', 'VIP', 148000000.00, 1), +('CUST060', 'International Supply', 'Isabella Thomas', 'isabella@intsupply.com', '+1-416-789-0', '741 Bay Street', 'Toronto', 'ON', 'Canada', 'Premium', 67000000.00, 1), +('CUST061', 'Future Systems', 'William Jackson', 'william@futuresys.com', '+81-3-1234', '852 Shibuya', 'Tokyo', 'Tokyo', 'Japan', 'VIP', 158000000.00, 1), +('CUST062', 'Green Energy Ltd', 'Olivia White', 'olivia@greenenergy.com', '+44-161-234', '963 Market Street', 'Manchester', 'England', 'UK', 'Regular', 43000000.00, 1), +('CUST063', 'Advanced Materials', 'Ethan Harris', 'ethan@advmaterials.com', '+49-89-5678', '159 Marienplatz', 'Munich', 'Bavaria', 'Germany', 'Premium', 78000000.00, 1), +('CUST064', 'Ocean Freight Co', 'Ava Martinez', 'ava@oceanfreight.com', '+31-20-1234', '357 Damrak', 'Amsterdam', 'NH', 'Netherlands', 'VIP', 142000000.00, 1), +('CUST065', 'Digital Commerce', 'Noah Robinson', 'noah@digicommerce.com', '+1-555-0104', '753 Commerce Street', 'Seattle', 'WA', 'USA', 'Premium', 89000000.00, 1), +('CUST066', 'Biotech Research', 'Mia Clark', 'mia@biotech.com', '+41-44-789', '951 Bahnhofstrasse', 'Zurich', 'ZH', 'Switzerland', 'VIP', 165000000.00, 1), +('CUST067', 'Automotive Parts Ltd', 'Lucas Rodriguez', 'lucas@autoparts.com', '+39-02-3456', '246 Via Montenapoleone', 'Milan', 'Lombardy', 'Italy', 'Regular', 48000000.00, 1), +('CUST068', 'Cloud Services Inc', 'Charlotte Lewis', 'charlotte@cloudserv.com', '+353-1-234', '468 OConnell Street', 'Dublin', 'Dublin', 'Ireland', 'Premium', 72000000.00, 1), +('CUST069', 'Pharma Solutions', 'Benjamin Walker', 'benjamin@pharmasol.com', '+32-2-5678', '579 Grand Place', 'Brussels', 'Brussels', 'Belgium', 'VIP', 128000000.00, 1), +('CUST070', 'Robotics International', 'Amelia Hall', 'amelia@robotics.com', '+82-2-1234', '681 Gangnam-gu', 'Seoul', 'Seoul', 'South Korea', 'Premium', 94000000.00, 1), +('CUST071', 'Financial Systems', 'Henry Allen', 'henry@finsys.com', '+1-555-0105', '792 Financial District', 'Chicago', 'IL', 'USA', 'VIP', 156000000.00, 1), +('CUST072', 'Renewable Power', 'Harper Young', 'harper@renewpower.com', '+45-33-1234', '813 Nyhavn', 'Copenhagen', 'Capital', 'Denmark', 'Regular', 51000000.00, 1), +('CUST073', 'Aerospace Tech', 'Alexander King', 'alex@aerotech.com', '+1-555-0106', '924 Aerospace Parkway', 'Houston', 'TX', 'USA', 'VIP', 175000000.00, 1), +('CUST074', 'Smart Agriculture', 'Evelyn Wright', 'evelyn@smartagri.com', '+31-10-5678', '135 Coolsingel', 'Rotterdam', 'ZH', 'Netherlands', 'Premium', 63000000.00, 1), +('CUST075', 'Quantum Computing', 'Sebastian Lopez', 'sebastian@quantum.com', '+1-555-0107', '246 Innovation Way', 'Boston', 'MA', 'USA', 'VIP', 182000000.00, 1), +('CUST076', 'Marine Solutions', 'Ella Hill', 'ella@marinesol.com', '+47-22-1234', '357 Stortorget', 'Oslo', 'Oslo', 'Norway', 'Regular', 46000000.00, 1), +('CUST077', 'AI Development', 'Jack Scott', 'jack@aidev.com', '+1-555-0108', '468 Tech Center', 'San Jose', 'CA', 'USA', 'Premium', 98000000.00, 1), +('CUST078', 'Logistics Solutions', 'Aria Green', 'aria@logisol.com', '+65-6234-5678', '579 Business Park', 'Singapore', 'Singapore', 'Singapore', 'VIP', 138000000.00, 1), +('CUST079', 'Construction Tech', 'Mason Adams', 'mason@constructech.com', '+61-3-1234', '691 Collins Street', 'Melbourne', 'VIC', 'Australia', 'Premium', 71000000.00, 1), +('CUST080', 'Food Processing', 'Luna Baker', 'luna@foodproc.com', '+34-91-234', '702 Gran Via', 'Madrid', 'Madrid', 'Spain', 'Regular', 42000000.00, 1), +('CUST081', 'Textile Manufacturing', 'Logan Nelson', 'logan@textilema.com', '+91-22-1234', '813 Marine Drive', 'Mumbai', 'MH', 'India', 'Premium', 54000000.00, 1), +('CUST082', 'Chemical Industries', 'Layla Carter', 'layla@chemind.com', '+55-11-5678', '924 Avenida Paulista', 'São Paulo', 'SP', 'Brazil', 'VIP', 132000000.00, 1), +('CUST083', 'Mining Corporation', 'Elijah Mitchell', 'elijah@miningcorp.com', '+27-11-234', '135 Commissioner St', 'Johannesburg', 'GP', 'South Africa', 'Premium', 87000000.00, 1), +('CUST084', 'Healthcare Systems', 'Chloe Perez', 'chloe@healthcare.com', '+1-555-0109', '246 Medical Center', 'Philadelphia', 'PA', 'USA', 'VIP', 149000000.00, 1), +('CUST085', 'Education Technology', 'Matthew Roberts', 'matthew@edutech.com', '+44-131-234', '357 Royal Mile', 'Edinburgh', 'Scotland', 'UK', 'Regular', 39000000.00, 1), +('CUST086', 'Entertainment Media', 'Avery Turner', 'avery@entmedia.com', '+1-555-0110', '468 Sunset Boulevard', 'Los Angeles', 'CA', 'USA', 'Premium', 76000000.00, 1), +('CUST087', 'Security Solutions', 'Daniel Phillips', 'daniel@secsol.com', '+972-3-1234', '579 Rothschild Blvd', 'Tel Aviv', 'TA', 'Israel', 'VIP', 124000000.00, 1), +('CUST088', 'Environmental Tech', 'Sofia Campbell', 'sofia@envtech.com', '+358-9-1234', '691 Esplanadi', 'Helsinki', 'Uusimaa', 'Finland', 'Premium', 69000000.00, 1), +('CUST089', 'Transportation Systems', 'Joseph Parker', 'joseph@transys.com', '+43-1-5678', '702 Ringstraße', 'Vienna', 'Vienna', 'Austria', 'Regular', 57000000.00, 1), +('CUST090', 'Telecommunications', 'Victoria Evans', 'victoria@telecom.com', '+852-2345-6789', '813 Nathan Road', 'Hong Kong', 'HK', 'Hong Kong', 'VIP', 167000000.00, 1), +('CUST091', 'Water Treatment', 'David Edwards', 'david@watertreat.com', '+971-4-1234', '924 Sheikh Zayed Rd', 'Dubai', 'Dubai', 'UAE', 'Premium', 102000000.00, 1), +('CUST092', 'Fashion Design', 'Grace Collins', 'grace@fashiondes.com', '+33-1-5678', '135 Rue de Rivoli', 'Paris', 'IDF', 'France', 'Regular', 44000000.00, 1), +('CUST093', 'Gaming Studios', 'Samuel Stewart', 'samuel@gamingstudios.com', '+1-555-0111', '246 Game Avenue', 'San Francisco', 'CA', 'USA', 'Premium', 91000000.00, 1), +('CUST094', 'Space Technology', 'Zoe Sanchez', 'zoe@spacetech.com', '+1-321-555-0112', '357 Kennedy Space Center', 'Cape Canaveral', 'FL', 'USA', 'VIP', 195000000.00, 1), +('CUST095', 'Furniture Design', 'Ryan Morris', 'ryan@furndes.com', '+46-31-1234', '468 Avenyn', 'Gothenburg', 'VG', 'Sweden', 'Regular', 49000000.00, 1), +('CUST096', 'Printing Services', 'Penelope Rogers', 'penelope@printserv.com', '+49-40-5678', '579 Jungfernstieg', 'Hamburg', 'Hamburg', 'Germany', 'Premium', 58000000.00, 1), +('CUST097', 'Packaging Solutions', 'Isaac Reed', 'isaac@packsol.com', '+1-555-0113', '691 Industrial Pkwy', 'Atlanta', 'GA', 'USA', 'VIP', 118000000.00, 1), +('CUST098', 'Laboratory Equipment', 'Stella Cook', 'stella@labequip.com', '+41-61-1234', '702 Basel Street', 'Basel', 'BS', 'Switzerland', 'Premium', 84000000.00, 1), +('CUST099', 'Sports Equipment', 'Christian Morgan', 'christian@sportseq.com', '+1-555-0114', '813 Sports Complex', 'Denver', 'CO', 'USA', 'Regular', 53000000.00, 1), +('CUST100', 'Defense Systems', 'Nora Bell', 'nora@defensesys.com', '+1-703-555-0115', '924 Pentagon Road', 'Arlington', 'VA', 'USA', 'VIP', 220000000.00, 1) GO --- ======================================== --- 5. 데이터 입력 결과 확인 --- ======================================== - -PRINT '' -PRINT '=== 데이터 입력 완료 ===' -PRINT '' - --- 테이블별 데이터 개수 확인 -SELECT 'Customers' as TableName, COUNT(*) as RecordCount FROM dbo.Customers -UNION ALL -SELECT 'Orders' as TableName, COUNT(*) as RecordCount FROM dbo.Orders -UNION ALL -SELECT 'OrderDetails' as TableName, COUNT(*) as RecordCount FROM dbo.OrderDetails - -PRINT '' -PRINT '=== 주문 상태별 집계 ===' - --- 주문 상태별 집계 -SELECT - OrderStatus, - COUNT(*) as OrderCount, - SUM(TotalAmount) as TotalAmount -FROM dbo.Orders -GROUP BY OrderStatus -ORDER BY OrderCount DESC - -PRINT '' -PRINT '=== 지역별 고객 수 ===' - --- 지역별 고객 수 -SELECT - Region, - COUNT(*) as CustomerCount -FROM dbo.Customers -WHERE IsActive = 1 -GROUP BY Region -ORDER BY CustomerCount DESC - -PRINT '' -PRINT '샘플 데이터 입력이 모두 완료되었습니다!' -GO \ No newline at end of file +-- (계속...) diff --git a/resources/insert_sample_data_100_preview.sql b/resources/insert_sample_data_100_preview.sql new file mode 100644 index 0000000..e69de29 diff --git a/resources/insert_sample_data_mysql.sql b/resources/insert_sample_data_mysql.sql new file mode 100644 index 0000000..b4d338a --- /dev/null +++ b/resources/insert_sample_data_mysql.sql @@ -0,0 +1,126 @@ +-- ======================================== +-- 샘플 데이터 입력 스크립트 +-- MySQL / MariaDB용 +-- ======================================== + +USE sampledb; + +-- ======================================== +-- 1. Customers 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES +('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, TRUE), +('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, TRUE), +('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, TRUE), +('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, TRUE), +('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, TRUE), +('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, TRUE), +('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, TRUE), +('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, TRUE), +('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, TRUE), +('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, TRUE); + +-- ======================================== +-- 2. Products 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES +('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, FALSE, '고성능 업무용 노트북'), +('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, FALSE, '인체공학적 디자인 무선 마우스'), +('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, FALSE, 'RGB 백라이트 기계식 키보드'), +('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, FALSE, '4K UHD 해상도 모니터'), +('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, FALSE, '초고속 데이터 전송 외장 SSD'), +('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, FALSE, 'USB 3.0 고속 메모리'), +('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, FALSE, '노이즈 캔슬링 기능'), +('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, FALSE, '방수 기능 휴대용 스피커'), +('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, FALSE, '1080p 화상회의용 웹캠'), +('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, FALSE, '안드로이드 태블릿'), +('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, FALSE, '흑백 레이저 프린터'), +('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, FALSE, '프린터/스캐너/복사기 일체형'), +('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, FALSE, 'LED 조명 각도조절 가능'), +('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, FALSE, '인체공학 메쉬 의자'), +('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, FALSE, '4단 서류 보관함'); + +-- ======================================== +-- 3. Employees 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES +('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, TRUE), +('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, TRUE), +('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, TRUE), +('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, TRUE), +('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, TRUE), +('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, TRUE), +('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, TRUE), +('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, TRUE), +('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, TRUE), +('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, TRUE); + +-- ======================================== +-- 4. Orders 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES +('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), +('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), +('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), +('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), +('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), +('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), +('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), +('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); + +-- ======================================== +-- 5. OrderDetails 테이블 데이터 입력 +-- ======================================== + +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES +-- Order 1 +(1, 1, 1500000.00, 2, 5.00), +-- Order 2 +(2, 2, 35000.00, 10, 0.00), +(2, 3, 120000.00, 5, 0.00), +(2, 6, 25000.00, 20, 0.00), +-- Order 3 +(3, 4, 450000.00, 3, 5.00), +(3, 5, 180000.00, 2, 5.00), +-- Order 4 +(4, 1, 1500000.00, 2, 10.00), +(4, 4, 450000.00, 2, 10.00), +(4, 7, 150000.00, 5, 10.00), +-- Order 5 +(5, 8, 80000.00, 10, 5.00), +(5, 9, 95000.00, 5, 5.00), +(5, 10, 450000.00, 1, 5.00), +-- Order 6 +(6, 11, 350000.00, 5, 5.00), +(6, 13, 45000.00, 20, 5.00), +-- Order 7 +(7, 12, 650000.00, 3, 10.00), +(7, 14, 250000.00, 10, 10.00), +-- Order 8 +(8, 15, 180000.00, 5, 0.00), +(8, 2, 35000.00, 10, 0.00), +-- Order 9 +(9, 6, 25000.00, 30, 0.00), +(9, 13, 45000.00, 5, 0.00), +-- Order 10 +(10, 1, 1500000.00, 1, 5.00), +(10, 7, 150000.00, 5, 5.00); + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample data inserted successfully for MySQL/MariaDB!' AS Message; +SELECT + 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers +UNION ALL SELECT 'Products', COUNT(*) FROM Products +UNION ALL SELECT 'Employees', COUNT(*) FROM Employees +UNION ALL SELECT 'Orders', COUNT(*) FROM Orders +UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; + diff --git a/resources/insert_sample_data_postgresql.sql b/resources/insert_sample_data_postgresql.sql new file mode 100644 index 0000000..fbc8d24 --- /dev/null +++ b/resources/insert_sample_data_postgresql.sql @@ -0,0 +1,123 @@ +-- ======================================== +-- 샘플 데이터 입력 스크립트 +-- PostgreSQL용 +-- ======================================== + +-- ======================================== +-- 1. Customers 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES +('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, TRUE), +('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, TRUE), +('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, TRUE), +('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, TRUE), +('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, TRUE), +('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, TRUE), +('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, TRUE), +('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, TRUE), +('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, TRUE), +('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, TRUE); + +-- ======================================== +-- 2. Products 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES +('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, FALSE, '고성능 업무용 노트북'), +('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, FALSE, '인체공학적 디자인 무선 마우스'), +('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, FALSE, 'RGB 백라이트 기계식 키보드'), +('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, FALSE, '4K UHD 해상도 모니터'), +('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, FALSE, '초고속 데이터 전송 외장 SSD'), +('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, FALSE, 'USB 3.0 고속 메모리'), +('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, FALSE, '노이즈 캔슬링 기능'), +('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, FALSE, '방수 기능 휴대용 스피커'), +('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, FALSE, '1080p 화상회의용 웹캠'), +('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, FALSE, '안드로이드 태블릿'), +('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, FALSE, '흑백 레이저 프린터'), +('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, FALSE, '프린터/스캐너/복사기 일체형'), +('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, FALSE, 'LED 조명 각도조절 가능'), +('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, FALSE, '인체공학 메쉬 의자'), +('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, FALSE, '4단 서류 보관함'); + +-- ======================================== +-- 3. Employees 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES +('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, TRUE), +('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, TRUE), +('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, TRUE), +('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, TRUE), +('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, TRUE), +('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, TRUE), +('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, TRUE), +('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, TRUE), +('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, TRUE), +('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, TRUE); + +-- ======================================== +-- 4. Orders 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES +('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), +('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), +('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), +('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), +('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), +('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), +('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), +('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); + +-- ======================================== +-- 5. OrderDetails 테이블 데이터 입력 +-- ======================================== + +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES +-- Order 1 +(1, 1, 1500000.00, 2, 5.00), +-- Order 2 +(2, 2, 35000.00, 10, 0.00), +(2, 3, 120000.00, 5, 0.00), +(2, 6, 25000.00, 20, 0.00), +-- Order 3 +(3, 4, 450000.00, 3, 5.00), +(3, 5, 180000.00, 2, 5.00), +-- Order 4 +(4, 1, 1500000.00, 2, 10.00), +(4, 4, 450000.00, 2, 10.00), +(4, 7, 150000.00, 5, 10.00), +-- Order 5 +(5, 8, 80000.00, 10, 5.00), +(5, 9, 95000.00, 5, 5.00), +(5, 10, 450000.00, 1, 5.00), +-- Order 6 +(6, 11, 350000.00, 5, 5.00), +(6, 13, 45000.00, 20, 5.00), +-- Order 7 +(7, 12, 650000.00, 3, 10.00), +(7, 14, 250000.00, 10, 10.00), +-- Order 8 +(8, 15, 180000.00, 5, 0.00), +(8, 2, 35000.00, 10, 0.00), +-- Order 9 +(9, 6, 25000.00, 30, 0.00), +(9, 13, 45000.00, 5, 0.00), +-- Order 10 +(10, 1, 1500000.00, 1, 5.00), +(10, 7, 150000.00, 5, 5.00); + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample data inserted successfully for PostgreSQL!' AS Message; +SELECT 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers +UNION ALL SELECT 'Products', COUNT(*) FROM Products +UNION ALL SELECT 'Employees', COUNT(*) FROM Employees +UNION ALL SELECT 'Orders', COUNT(*) FROM Orders +UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; + diff --git a/resources/insert_sample_data_sqlite.sql b/resources/insert_sample_data_sqlite.sql new file mode 100644 index 0000000..d3e7f83 --- /dev/null +++ b/resources/insert_sample_data_sqlite.sql @@ -0,0 +1,123 @@ +-- ======================================== +-- 샘플 데이터 입력 스크립트 +-- SQLite용 +-- ======================================== + +-- ======================================== +-- 1. Customers 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES +('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, 1), +('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, 1), +('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, 1), +('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, 1), +('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, 1), +('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, 1), +('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, 1), +('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, 1), +('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, 1), +('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, 1); + +-- ======================================== +-- 2. Products 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES +('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, 0, '고성능 업무용 노트북'), +('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, 0, '인체공학적 디자인 무선 마우스'), +('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, 0, 'RGB 백라이트 기계식 키보드'), +('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, 0, '4K UHD 해상도 모니터'), +('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, 0, '초고속 데이터 전송 외장 SSD'), +('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, 0, 'USB 3.0 고속 메모리'), +('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, 0, '노이즈 캔슬링 기능'), +('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, 0, '방수 기능 휴대용 스피커'), +('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, 0, '1080p 화상회의용 웹캠'), +('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, 0, '안드로이드 태블릿'), +('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, 0, '흑백 레이저 프린터'), +('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, 0, '프린터/스캐너/복사기 일체형'), +('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, 0, 'LED 조명 각도조절 가능'), +('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, 0, '인체공학 메쉬 의자'), +('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, 0, '4단 서류 보관함'); + +-- ======================================== +-- 3. Employees 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES +('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, 1), +('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, 1), +('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, 1), +('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, 1), +('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, 1), +('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, 1), +('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, 1), +('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, 1), +('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, 1), +('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, 1); + +-- ======================================== +-- 4. Orders 테이블 데이터 입력 +-- ======================================== + +INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES +('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), +('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), +('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), +('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), +('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), +('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), +('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), +('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), +('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); + +-- ======================================== +-- 5. OrderDetails 테이블 데이터 입력 +-- ======================================== + +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES +-- Order 1 +(1, 1, 1500000.00, 2, 5.00), +-- Order 2 +(2, 2, 35000.00, 10, 0.00), +(2, 3, 120000.00, 5, 0.00), +(2, 6, 25000.00, 20, 0.00), +-- Order 3 +(3, 4, 450000.00, 3, 5.00), +(3, 5, 180000.00, 2, 5.00), +-- Order 4 +(4, 1, 1500000.00, 2, 10.00), +(4, 4, 450000.00, 2, 10.00), +(4, 7, 150000.00, 5, 10.00), +-- Order 5 +(5, 8, 80000.00, 10, 5.00), +(5, 9, 95000.00, 5, 5.00), +(5, 10, 450000.00, 1, 5.00), +-- Order 6 +(6, 11, 350000.00, 5, 5.00), +(6, 13, 45000.00, 20, 5.00), +-- Order 7 +(7, 12, 650000.00, 3, 10.00), +(7, 14, 250000.00, 10, 10.00), +-- Order 8 +(8, 15, 180000.00, 5, 0.00), +(8, 2, 35000.00, 10, 0.00), +-- Order 9 +(9, 6, 25000.00, 30, 0.00), +(9, 13, 45000.00, 5, 0.00), +-- Order 10 +(10, 1, 1500000.00, 1, 5.00), +(10, 7, 150000.00, 5, 5.00); + +-- ======================================== +-- 완료 메시지 +-- ======================================== + +SELECT 'Sample data inserted successfully for SQLite!' AS Message; +SELECT 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers +UNION ALL SELECT 'Products', COUNT(*) FROM Products +UNION ALL SELECT 'Employees', COUNT(*) FROM Employees +UNION ALL SELECT 'Orders', COUNT(*) FROM Orders +UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; + From b53968ecc61623b13842da72d6b04312df96f84d Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Tue, 4 Nov 2025 21:23:41 +0900 Subject: [PATCH 10/25] Added Oracle to supported databases --- config/dbinfo.json | 17 +- package.json | 4 +- queries/oracle-test.xml | 47 +++++ resources/create_sample_tables_oracle.sql | 209 ++++++++++++++++++++++ resources/drop_sample_tables_oracle.sql | 16 ++ resources/insert_sample_data_oracle.sql | 45 +++++ src/database/DatabaseFactory.js | 9 +- src/database/OracleAdapter.js | 186 +++++++++++++++++++ 8 files changed, 530 insertions(+), 3 deletions(-) create mode 100644 queries/oracle-test.xml create mode 100644 resources/create_sample_tables_oracle.sql create mode 100644 resources/drop_sample_tables_oracle.sql create mode 100644 resources/insert_sample_data_oracle.sql create mode 100644 src/database/OracleAdapter.js diff --git a/config/dbinfo.json b/config/dbinfo.json index d34949f..da5f894 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -75,5 +75,20 @@ "options": { "mode": null } + }, + "oracleDB": { + "type": "oracle", + "user": "system", + "password": "oracle", + "server": "localhost", + "port": 1521, + "serviceName": "XEPDB1", + "options": { + "poolMin": 0, + "poolMax": 4, + "poolIncrement": 1, + "queueTimeout": 30000, + "stmtCacheSize": 30 + } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/package.json b/package.json index 4b736a2..11954ea 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "node_modules/tedious/**/*", "node_modules/mysql2/**/*", "node_modules/pg/**/*", - "node_modules/better-sqlite3/**/*" + "node_modules/better-sqlite3/**/*", + "node_modules/oracledb/**/*" ], "targets": [ "node18-win-x64" @@ -45,6 +46,7 @@ "mssql": "^10.0.0", "mysql2": "^3.4.0", "pg": "^8.16.3", + "oracledb": "^6.6.0", "xml2js": "^0.6.2", "yargs": "^17.7.2" }, diff --git a/queries/oracle-test.xml b/queries/oracle-test.xml new file mode 100644 index 0000000..2293e88 --- /dev/null +++ b/queries/oracle-test.xml @@ -0,0 +1,47 @@ + + + + + + + + SELECT USER as username, SYS_CONTEXT('USERENV','DB_NAME') as db_name, SYSDATE as sysdate FROM dual + + + + + + SELECT + owner, + table_name, + num_rows, + blocks, + to_char(last_analyzed,'YYYY-MM-DD HH24:MI:SS') as last_analyzed + FROM all_tables + WHERE owner = USER + ORDER BY table_name + FETCH FIRST 50 ROWS ONLY + + + + + + SELECT + c.CustomerID, + c.CustomerCode, + c.CustomerName, + c.City, + c.Region, + c.Country, + c.CreditLimit, + c.IsActive, + to_char(c.CreatedDate, 'YYYY-MM-DD HH24:MI:SS') as CreatedDate + FROM Customers c + ORDER BY c.CustomerID + FETCH FIRST 100 ROWS ONLY + + + diff --git a/resources/create_sample_tables_oracle.sql b/resources/create_sample_tables_oracle.sql new file mode 100644 index 0000000..90ccbb3 --- /dev/null +++ b/resources/create_sample_tables_oracle.sql @@ -0,0 +1,209 @@ +-- ======================================== +-- 샘플 테이블 생성 스크립트 +-- Oracle Database용 (12c 이상 권장) +-- ======================================== + +-- 주의: 스키마는 현재 접속 사용자로 생성됩니다. 필요 시 다른 스키마로 변경하세요. + +-- 기존 객체 삭제 (존재 시) +BEGIN EXECUTE IMMEDIATE 'DROP VIEW vw_OrderSummary'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE OrderDetails CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Orders CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Products CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Employees CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Customers CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ + +-- ======================================== +-- 1. Customers 테이블 +-- ======================================== +CREATE TABLE Customers ( + CustomerID NUMBER GENERATED BY DEFAULT AS IDENTITY, + CustomerCode VARCHAR2(20) NOT NULL, + CustomerName VARCHAR2(100) NOT NULL, + ContactName VARCHAR2(50), + Email VARCHAR2(100), + Phone VARCHAR2(20), + Address VARCHAR2(200), + City VARCHAR2(50), + Region VARCHAR2(50), + PostalCode VARCHAR2(10), + Country VARCHAR2(50), + CustomerType VARCHAR2(20) DEFAULT 'Regular', + CreditLimit NUMBER(15,2) DEFAULT 0, + IsActive NUMBER(1) DEFAULT 1, + CreatedDate TIMESTAMP DEFAULT SYSTIMESTAMP, + LastUpdated TIMESTAMP DEFAULT SYSTIMESTAMP, + CONSTRAINT PK_Customers PRIMARY KEY (CustomerID), + CONSTRAINT UK_Customers_Code UNIQUE (CustomerCode) +); + +CREATE INDEX IX_Customers_Name ON Customers (CustomerName); +CREATE INDEX IX_Customers_City ON Customers (City); +CREATE INDEX IX_Customers_Region ON Customers (Region); +CREATE INDEX IX_Customers_Type ON Customers (CustomerType); + +-- LastUpdated 자동 업데이트 트리거 +CREATE OR REPLACE TRIGGER trg_customers_modtime +BEFORE UPDATE ON Customers +FOR EACH ROW +BEGIN + :NEW.LastUpdated := SYSTIMESTAMP; +END; +/ + +-- ======================================== +-- 2. Orders 테이블 +-- ======================================== +CREATE TABLE Orders ( + OrderID NUMBER GENERATED BY DEFAULT AS IDENTITY, + OrderNumber VARCHAR2(30) NOT NULL, + CustomerID NUMBER NOT NULL, + OrderDate TIMESTAMP NOT NULL, + RequiredDate TIMESTAMP, + ShippedDate TIMESTAMP, + OrderStatus VARCHAR2(20) DEFAULT 'Pending', + SubTotal NUMBER(15,2) DEFAULT 0, + TaxAmount NUMBER(15,2) DEFAULT 0, + TotalAmount NUMBER(15,2) DEFAULT 0, + PaymentMethod VARCHAR2(30), + PaymentStatus VARCHAR2(20) DEFAULT 'Unpaid', + EmployeeID NUMBER, + Notes VARCHAR2(500), + CreatedDate TIMESTAMP DEFAULT SYSTIMESTAMP, + LastUpdated TIMESTAMP DEFAULT SYSTIMESTAMP, + CONSTRAINT PK_Orders PRIMARY KEY (OrderID), + CONSTRAINT UK_Orders_Number UNIQUE (OrderNumber), + CONSTRAINT FK_Orders_Customers FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) +); + +CREATE INDEX IX_Orders_CustomerID ON Orders (CustomerID); +CREATE INDEX IX_Orders_OrderDate ON Orders (OrderDate); +CREATE INDEX IX_Orders_Status ON Orders (OrderStatus); +CREATE INDEX IX_Orders_PaymentStatus ON Orders (PaymentStatus); +CREATE INDEX IX_Orders_ShippedDate ON Orders (ShippedDate); + +CREATE OR REPLACE TRIGGER trg_orders_modtime +BEFORE UPDATE ON Orders +FOR EACH ROW +BEGIN + :NEW.LastUpdated := SYSTIMESTAMP; +END; +/ + +-- ======================================== +-- 3. Products 테이블 +-- ======================================== +CREATE TABLE Products ( + ProductID NUMBER GENERATED BY DEFAULT AS IDENTITY, + ProductCode VARCHAR2(20) NOT NULL, + ProductName VARCHAR2(100) NOT NULL, + Category VARCHAR2(50), + UnitPrice NUMBER(15,2) DEFAULT 0, + UnitsInStock NUMBER DEFAULT 0, + UnitsOnOrder NUMBER DEFAULT 0, + ReorderLevel NUMBER DEFAULT 0, + Discontinued NUMBER(1) DEFAULT 0, + Description CLOB, + CreatedDate TIMESTAMP DEFAULT SYSTIMESTAMP, + LastUpdated TIMESTAMP DEFAULT SYSTIMESTAMP, + CONSTRAINT PK_Products PRIMARY KEY (ProductID), + CONSTRAINT UK_Products_Code UNIQUE (ProductCode) +); + +CREATE INDEX IX_Products_Name ON Products (ProductName); +CREATE INDEX IX_Products_Category ON Products (Category); +CREATE INDEX IX_Products_Price ON Products (UnitPrice); + +CREATE OR REPLACE TRIGGER trg_products_modtime +BEFORE UPDATE ON Products +FOR EACH ROW +BEGIN + :NEW.LastUpdated := SYSTIMESTAMP; +END; +/ + +-- ======================================== +-- 4. OrderDetails 테이블 +-- ======================================== +CREATE TABLE OrderDetails ( + OrderDetailID NUMBER GENERATED BY DEFAULT AS IDENTITY, + OrderID NUMBER NOT NULL, + ProductID NUMBER NOT NULL, + UnitPrice NUMBER(15,2) NOT NULL, + Quantity NUMBER NOT NULL, + Discount NUMBER(5,2) DEFAULT 0, + LineTotal NUMBER(15,2) GENERATED ALWAYS AS (UnitPrice * Quantity * (1 - Discount/100)) VIRTUAL, + CreatedDate TIMESTAMP DEFAULT SYSTIMESTAMP, + CONSTRAINT PK_OrderDetails PRIMARY KEY (OrderDetailID), + CONSTRAINT FK_OrderDetails_Orders FOREIGN KEY (OrderID) REFERENCES Orders(OrderID) ON DELETE CASCADE, + CONSTRAINT FK_OrderDetails_Products FOREIGN KEY (ProductID) REFERENCES Products(ProductID) +); + +CREATE INDEX IX_OrderDetails_OrderID ON OrderDetails (OrderID); +CREATE INDEX IX_OrderDetails_ProductID ON OrderDetails (ProductID); + +-- ======================================== +-- 5. Employees 테이블 +-- ======================================== +CREATE TABLE Employees ( + EmployeeID NUMBER GENERATED BY DEFAULT AS IDENTITY, + EmployeeCode VARCHAR2(20) NOT NULL, + FirstName VARCHAR2(50) NOT NULL, + LastName VARCHAR2(50) NOT NULL, + Title VARCHAR2(50), + BirthDate DATE, + HireDate DATE, + Email VARCHAR2(100), + Phone VARCHAR2(20), + Department VARCHAR2(50), + Salary NUMBER(15,2), + ReportsTo NUMBER, + IsActive NUMBER(1) DEFAULT 1, + CreatedDate TIMESTAMP DEFAULT SYSTIMESTAMP, + LastUpdated TIMESTAMP DEFAULT SYSTIMESTAMP, + CONSTRAINT PK_Employees PRIMARY KEY (EmployeeID), + CONSTRAINT UK_Employees_Code UNIQUE (EmployeeCode), + CONSTRAINT FK_Employees_ReportsTo FOREIGN KEY (ReportsTo) REFERENCES Employees(EmployeeID) +); + +CREATE INDEX IX_Employees_Name ON Employees (LastName, FirstName); +CREATE INDEX IX_Employees_Department ON Employees (Department); +CREATE INDEX IX_Employees_ReportsTo ON Employees (ReportsTo); + +CREATE OR REPLACE TRIGGER trg_employees_modtime +BEFORE UPDATE ON Employees +FOR EACH ROW +BEGIN + :NEW.LastUpdated := SYSTIMESTAMP; +END; +/ + +-- ======================================== +-- 6. 주문 요약 뷰 +-- ======================================== +CREATE OR REPLACE VIEW vw_OrderSummary AS +SELECT + o.OrderID, + o.OrderNumber, + o.OrderDate, + c.CustomerCode, + c.CustomerName, + c.City AS CustomerCity, + c.Region AS CustomerRegion, + o.OrderStatus, + o.PaymentStatus, + o.TotalAmount, + (SELECT COUNT(*) FROM OrderDetails od WHERE od.OrderID = o.OrderID) AS ItemCount, + (SELECT NVL(SUM(od.Quantity),0) FROM OrderDetails od WHERE od.OrderID = o.OrderID) AS TotalQuantity, + o.CreatedDate +FROM Orders o +JOIN Customers c ON o.CustomerID = c.CustomerID; + +-- 완료 메시지 +PROMPT 'Oracle용 샘플 테이블 생성 완료' diff --git a/resources/drop_sample_tables_oracle.sql b/resources/drop_sample_tables_oracle.sql new file mode 100644 index 0000000..1aa10f6 --- /dev/null +++ b/resources/drop_sample_tables_oracle.sql @@ -0,0 +1,16 @@ +-- ======================================== +-- 샘플 테이블/뷰 삭제 스크립트 (Oracle) +-- ======================================== +BEGIN EXECUTE IMMEDIATE 'DROP VIEW vw_OrderSummary'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE OrderDetails CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Orders CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Products CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Employees CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +BEGIN EXECUTE IMMEDIATE 'DROP TABLE Customers CASCADE CONSTRAINTS'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END; +/ +PROMPT 'Oracle용 샘플 객체 삭제 완료' diff --git a/resources/insert_sample_data_oracle.sql b/resources/insert_sample_data_oracle.sql new file mode 100644 index 0000000..a98a444 --- /dev/null +++ b/resources/insert_sample_data_oracle.sql @@ -0,0 +1,45 @@ +-- ======================================== +-- 샘플 데이터 입력 스크립트 (Oracle) +-- ======================================== + +-- Customers +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) +VALUES ('CUST001','Acme Corp','John Doe','john@acme.com','+1-555-1001','New York','NY','USA','Regular',10000,1); +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) +VALUES ('CUST002','Globex','Jane Smith','jane@globex.com','+1-555-1002','Los Angeles','CA','USA','VIP',20000,1); +INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) +VALUES ('CUST003','Initech','Bob Martin','bob@initech.com','+1-555-1003','Seattle','WA','USA','Regular',15000,1); + +-- Products +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) +VALUES ('P-100','Laptop 14"','Electronics',1200,50); +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) +VALUES ('P-101','Wireless Mouse','Electronics',25,500); +INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) +VALUES ('P-102','Office Chair','Furniture',180,120); + +-- Employees +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) +VALUES ('E-001','Alice','Kim','Manager','Sales',6500,1); +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) +VALUES ('E-002','Brian','Lee','Engineer','IT',7200,1); +INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) +VALUES ('E-003','Cathy','Park','Analyst','Finance',5800,1); + +-- Orders +INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentStatus) +VALUES ('SO-20240101-001', 1, TO_TIMESTAMP('2024-01-01 10:00:00','YYYY-MM-DD HH24:MI:SS'), 'Pending', 1225, 122.5, 1347.5, 'Unpaid'); +INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentStatus) +VALUES ('SO-20240105-002', 2, TO_TIMESTAMP('2024-01-05 15:30:00','YYYY-MM-DD HH24:MI:SS'), 'Shipped', 180, 18, 198, 'Paid'); + +-- OrderDetails +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) +VALUES (1, 1, 1200, 1, 0); +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) +VALUES (1, 2, 25, 1, 0); +INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) +VALUES (2, 3, 180, 1, 0); + +COMMIT; + +PROMPT 'Oracle용 샘플 데이터 입력 완료' diff --git a/src/database/DatabaseFactory.js b/src/database/DatabaseFactory.js index 0cfd054..2f3ddb7 100644 --- a/src/database/DatabaseFactory.js +++ b/src/database/DatabaseFactory.js @@ -2,6 +2,7 @@ const MSSQLAdapter = require('./MSSQLAdapter'); const MySQLAdapter = require('./MySQLAdapter'); const PostgreSQLAdapter = require('./PostgreSQLAdapter'); const SQLiteAdapter = require('./SQLiteAdapter'); +const OracleAdapter = require('./OracleAdapter'); const { getMessages } = require('../utils/messages'); /** @@ -37,6 +38,11 @@ class DatabaseFactory { case 'sqlite3': return new SQLiteAdapter(config, language); + case 'oracle': + case 'oracledb': + case 'oci': + return new OracleAdapter(config, language); + default: throw new Error(`${msg.unsupportedDbType} ${dbType}`); } @@ -52,7 +58,8 @@ class DatabaseFactory { { type: 'mysql', name: 'MySQL', defaultPort: 3306 }, { type: 'mariadb', name: 'MariaDB', defaultPort: 3306 }, { type: 'postgresql', name: 'PostgreSQL', defaultPort: 5432 }, - { type: 'sqlite', name: 'SQLite', defaultPort: null } + { type: 'sqlite', name: 'SQLite', defaultPort: null }, + { type: 'oracle', name: 'Oracle Database', defaultPort: 1521 } ]; } diff --git a/src/database/OracleAdapter.js b/src/database/OracleAdapter.js new file mode 100644 index 0000000..8f5f5e5 --- /dev/null +++ b/src/database/OracleAdapter.js @@ -0,0 +1,186 @@ +const oracledb = require('oracledb'); +const { getMessages } = require('../utils/messages'); +const { formatDate, createInClause } = require('../utils/date-utils'); + +/** + * Oracle 데이터베이스 어댑터 + */ +class OracleAdapter { + constructor(config, language = 'en') { + this.config = config; + this.msg = getMessages('database', language); + this.dbPools = {}; + this.dbType = 'oracle'; + + // Recommended for performance + oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT; + } + + /** + * Oracle 연결 풀 생성 + * @param {Object} config - Oracle 연결 설정 + * @param {string} dbKey - 데이터베이스 키 + * @returns {Promise} 연결 풀 + */ + async createConnectionPool(config, dbKey) { + if (!this.dbPools[dbKey]) { + if (!config) { + throw new Error(`${this.msg.dbIdNotFound} ${dbKey}`); + } + + console.log(`[DB] ${dbKey} ${this.msg.dbConnecting}`); + + const host = config.server; + const port = parseInt(config.port, 10) || 1521; + const serviceName = config.serviceName || config.sid || config.database; + const connectString = config.connectString || `${host}:${port}/${serviceName}`; + + const poolConfig = { + user: config.user, + password: config.password, + connectString, + poolMin: config.options?.poolMin ?? 0, + poolMax: config.options?.poolMax ?? 4, + poolIncrement: config.options?.poolIncrement ?? 1, + queueTimeout: config.options?.queueTimeout ?? 30000, + stmtCacheSize: config.options?.stmtCacheSize ?? 30 + }; + + try { + const pool = await oracledb.createPool(poolConfig); + // Test a simple query + const conn = await pool.getConnection(); + await conn.execute('SELECT 1 FROM dual'); + await conn.close(); + this.dbPools[dbKey] = pool; + console.log(`[DB] ${dbKey} ${this.msg.dbConnected}`); + } catch (error) { + throw error; + } + } + return this.dbPools[dbKey]; + } + + /** + * Oracle 쿼리 실행 + * @param {oracledb.Pool} pool - 연결 풀 + * @param {string} sql - SQL 쿼리 + * @returns {Promise} 쿼리 결과 (MSSQL 형식과 호환) + */ + async executeQuery(pool, sql) { + let connection; + try { + connection = await pool.getConnection(); + const result = await connection.execute(sql); + + const rows = result.rows || []; + + return { + recordset: rows, + recordsets: [rows], + rowsAffected: [result.rowsAffected ?? (Array.isArray(rows) ? rows.length : 0)], + output: {}, + rowCount: Array.isArray(rows) ? rows.length : 0 + }; + } catch (error) { + throw error; + } finally { + if (connection) { + try { await connection.close(); } catch (_) {} + } + } + } + + /** + * Oracle 페이징/제한절 추가 (12c+): FETCH FIRST N ROWS ONLY + */ + addTopClause(sql, maxRows) { + if (!maxRows || maxRows <= 0) return sql; + const upper = sql.trim().toUpperCase(); + if (upper.includes('FETCH FIRST') || upper.includes('ROWNUM')) return sql; + return `${sql.trim()} FETCH FIRST ${maxRows} ROWS ONLY`; + } + + /** + * GETDATE() 치환 → SYSTIMESTAMP + */ + replaceGetDateFunction(sql) { + return sql.replace(/\bGETDATE\(\)\b/gi, 'SYSTIMESTAMP'); + } + + /** 날짜 포맷팅 위임 */ + formatDate(date, format) { return formatDate(date, format); } + + /** IN 절 생성 위임 */ + createInClause(values) { return createInClause(values); } + + /** + * Oracle 연결 설정 검증 + */ + validateConnectionConfig(config) { + const requiredFields = ['server', 'user', 'password']; + const hasHost = requiredFields.every(field => config.hasOwnProperty(field)); + const hasService = !!(config.serviceName || config.sid || config.database || config.connectString); + return hasHost && hasService; + } + + /** 연결 종료 */ + async closeConnection(dbKey) { + if (this.dbPools[dbKey]) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await this.dbPools[dbKey].close(10); + } catch (error) { + console.warn(`Warning: Oracle disconnect error: ${error.message}`); + } + delete this.dbPools[dbKey]; + } + } + + /** 모든 연결 종료 */ + async closeAllConnections() { + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + console.log(`[DB] ${dbKey} ${this.msg.dbClosing}`); + try { + await pool.close(10); + } catch (error) { + console.warn(`Warning: Oracle disconnect error: ${error.message}`); + } + } + this.dbPools = {}; + } + + /** 에러 메시지 매핑 */ + formatErrorMessage(error) { + const message = error.message || ''; + if (message.includes('ORA-01017')) { + return this.msg.errorAuth; + } else if (message.includes('DPI-1047')) { + return 'Oracle Client not found: Install Oracle Instant Client and set PATH.'; + } else if (message.includes('ORA-12154') || message.includes('ORA-12514') || message.includes('ORA-12541')) { + return this.msg.errorConnection; + } else if (message.includes('ORA-12545') || message.includes('ETIMEDOUT') || message.includes('ECONNREFUSED')) { + return this.msg.errorConnection; + } + return `Oracle Error: ${message}`; + } + + /** 연결 상태 */ + isConnected(dbKey) { + return this.dbPools[dbKey] !== undefined; + } + + /** 연결 풀 정보 */ + getConnectionInfo() { + const info = {}; + for (const [dbKey, pool] of Object.entries(this.dbPools)) { + info[dbKey] = { connected: true, poolMin: pool.poolMin, poolMax: pool.poolMax, connectionsOpen: pool.connectionsOpen }; + } + return info; + } + + /** DB 타입 */ + getType() { return this.dbType; } +} + +module.exports = OracleAdapter; From 7ee6ea4e17ae750ef02ce77c016bfddd1d5d7675 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Tue, 4 Nov 2025 21:44:52 +0900 Subject: [PATCH 11/25] Improved function to generate sample data --- resources/generate_sample_data.py | 274 ++++++++++++++++++++++++++---- 1 file changed, 240 insertions(+), 34 deletions(-) diff --git a/resources/generate_sample_data.py b/resources/generate_sample_data.py index 86f1314..004e116 100644 --- a/resources/generate_sample_data.py +++ b/resources/generate_sample_data.py @@ -7,6 +7,9 @@ import random from datetime import datetime, timedelta +import argparse +import os +import sys # 한글 데이터 korean_companies = [ @@ -112,40 +115,243 @@ ('Storage Locker', 'Furniture'), ('Privacy Screen', 'Furniture') ] -def generate_mssql_customers(): - """MSSQL용 Customers INSERT 문 생성""" - sql = [] - - for i in range(50): - code = f"'CUST{i+1:03d}'" - company = f"'(주){korean_companies[i]}'" if i < 10 else f"'{korean_companies[i]}'" - name = f"'{korean_names[i]}'" - email = f"'{korean_names[i].replace(' ', '').lower()}@{korean_companies[i].replace(' ', '').lower()}.co.kr'" - phone = f"'02-{random.randint(1000,9999)}-{random.randint(1000,9999)}'" - city = f"'{korean_cities[i % len(korean_cities)]}'" - region = f"'{korean_regions[i % len(korean_regions)]}'" - ctype = random.choice(['Premium', 'Regular', 'VIP']) - credit = random.randint(150, 2000) * 100000 - - sql.append(f"({code}, {company}, {name}, {email}, {phone}, '서울시 강남구', {city}, {region}, '대한민국', '{ctype}', {credit}.00, 1)") - - for i in range(50): - code = f"'CUST{i+51:03d}'" - company = f"'{english_companies[i]}'" - name = f"'{english_names[i]}'" - email = f"'{english_names[i].split()[0].lower()}@{english_companies[i].split()[0].lower()}.com'" - phone = f"'+1-555-{random.randint(1000,9999)}'" - city = f"'{english_cities[i]}'" - ctype = random.choice(['Premium', 'Regular', 'VIP']) - credit = random.randint(200, 2500) * 100000 - - sql.append(f"({code}, {company}, {name}, {email}, {phone}, 'Address', {city}, 'State', 'USA', '{ctype}', {credit}.00, 1)") - - return ",\n".join(sql) +def _fmt_str(s): + return "'" + str(s).replace("'", "''") + "'" + +def _fmt_bool(dialect, v): + if dialect == 'postgresql': + return 'TRUE' if v else 'FALSE' + # others accept 1/0, Oracle uses NUMBER(1) + return '1' if v else '0' + +def _fmt_dt_str(dt): + return dt.strftime('%Y-%m-%d %H:%M:%S') + +def _fmt_datetime(dialect, dt): + s = _fmt_dt_str(dt) + if dialect == 'oracle': + return f"TO_TIMESTAMP({_fmt_str(s)}, 'YYYY-MM-DD HH24:MI:SS')" + return _fmt_str(s) + +def _now(): + return datetime.utcnow() + +def gen_customers(rows): + data = [] + for i in range(rows // 2): + data.append({ + 'code': f"CUST{i+1:03d}", + 'name': ("(주)" if i < 10 else "") + korean_companies[i % len(korean_companies)], + 'contact': korean_names[i % len(korean_names)], + 'email': f"{korean_names[i % len(korean_names)].replace(' ', '').lower()}@{korean_companies[i % len(korean_companies)].replace(' ', '').lower()}.co.kr", + 'phone': f"02-{random.randint(1000,9999)}-{random.randint(1000,9999)}", + 'address': '서울시 강남구', + 'city': korean_cities[i % len(korean_cities)], + 'region': korean_regions[i % len(korean_regions)], + 'country': '대한민국', + 'ctype': random.choice(['Premium','Regular','VIP']), + 'credit': float(random.randint(150,2000) * 100000), + 'active': True + }) + for i in range(rows - len(data)): + data.append({ + 'code': f"CUST{i+1+len(data):03d}", + 'name': english_companies[i % len(english_companies)], + 'contact': english_names[i % len(english_names)], + 'email': f"{english_names[i % len(english_names)].split()[0].lower()}@{english_companies[i % len(english_companies)].split()[0].lower()}.com", + 'phone': f"+1-555-{random.randint(1000,9999)}", + 'address': 'Address', + 'city': english_cities[i % len(english_cities)], + 'region': 'State', + 'country': 'USA', + 'ctype': random.choice(['Premium','Regular','VIP']), + 'credit': float(random.randint(200,2500) * 100000), + 'active': True + }) + return data + +def gen_products(rows): + data = [] + for i in range(rows // 2): + name, cat = korean_products[i % len(korean_products)] + data.append({ + 'code': f"P-{100+i}", 'name': name, 'cat': cat, + 'price': round(random.uniform(10, 2000), 2), + 'stock': random.randint(0, 500), 'onorder': random.randint(0, 200), + 'reorder': random.randint(0, 50), 'disc': False, + 'desc': None + }) + for i in range(rows - len(data)): + name, cat = english_products[i % len(english_products)] + data.append({ + 'code': f"P-{200+i}", 'name': name, 'cat': cat, + 'price': round(random.uniform(10, 2000), 2), + 'stock': random.randint(0, 500), 'onorder': random.randint(0, 200), + 'reorder': random.randint(0, 50), 'disc': False, + 'desc': None + }) + return data + +def gen_employees(rows): + data = [] + base = datetime(1980, 1, 1) + for i in range(rows): + first = random.choice(['Alice','Brian','Cathy','David','Evan','Fiona','George','Hanna','Ian','Julia']) + last = random.choice(['Kim','Lee','Park','Choi','Jung','Kang','Yoon','Lim','Song','Han']) + hire = _now() - timedelta(days=random.randint(0, 3650)) + birth = datetime(1970,1,1) + timedelta(days=random.randint(0, 20000)) + data.append({ + 'code': f"E-{i+1:03d}", 'first': first, 'last': last, + 'title': random.choice(['Manager','Engineer','Analyst','Assistant','Director']), + 'birth': birth.date(), 'hire': hire.date(), + 'email': f"{first.lower()}.{last.lower()}@example.com", + 'phone': f"010-{random.randint(1000,9999)}-{random.randint(1000,9999)}", + 'dept': random.choice(['Sales','IT','Finance','HR','Marketing']), + 'salary': round(random.uniform(3000,9000),2), + 'reports': None if i==0 else random.randint(1, i), + 'active': True + }) + return data + +def gen_orders(rows, customers_count, employees_count): + data = [] + start = datetime(2024,1,1) + for i in range(rows): + odt = start + timedelta(days=random.randint(0,60), hours=random.randint(0,23), minutes=random.randint(0,59)) + ship = None if random.random() < 0.3 else (odt + timedelta(days=random.randint(1,7))) + req = odt + timedelta(days=random.randint(1,10)) + subtotal = round(random.uniform(50, 5000), 2) + tax = round(subtotal * 0.1, 2) + total = round(subtotal + tax, 2) + data.append({ + 'number': f"SO-2024{i+1:05d}", + 'customer_id': random.randint(1, customers_count), + 'order_date': odt, + 'required_date': req, + 'shipped_date': ship, + 'status': random.choice(['Pending','Shipped','Delivered']), + 'subtotal': subtotal, + 'tax': tax, + 'total': total, + 'pay_method': random.choice(['Card','Wire','Cash']), + 'pay_status': random.choice(['Unpaid','Paid']), + 'emp_id': random.randint(1, max(1, employees_count)), + 'notes': None + }) + return data + +def gen_order_details(rows, orders_count, products_count): + data = [] + for _ in range(rows): + qty = random.randint(1,5) + price = round(random.uniform(5, 2000),2) + data.append({ + 'order_id': random.randint(1, orders_count), + 'product_id': random.randint(1, products_count), + 'unit_price': price, + 'qty': qty, + 'discount': round(random.choice([0,0,0,5,10]),2) + }) + return data + +def render_inserts(dialect, table, rows): + lines = [] + if table == 'customers': + cols = '(CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive)' + for r in rows: + vals = [ + _fmt_str(r['code']), _fmt_str(r['name']), _fmt_str(r['contact']), _fmt_str(r['email']), _fmt_str(r['phone']), + _fmt_str(r['address']), _fmt_str(r['city']), _fmt_str(r['region']), _fmt_str(r['country']), _fmt_str(r['ctype']), + f"{r['credit']:.2f}", _fmt_bool(dialect, r['active']) + ] + lines.append(f"INSERT INTO Customers {cols} VALUES (" + ", ".join(vals) + ");") + elif table == 'products': + cols = '(ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description)' + for r in rows: + vals = [ + _fmt_str(r['code']), _fmt_str(r['name']), _fmt_str(r['cat']), f"{r['price']:.2f}", + str(r['stock']), str(r['onorder']), str(r['reorder']), _fmt_bool(dialect, r['disc']), 'NULL' if r['desc'] is None else _fmt_str(r['desc']) + ] + lines.append(f"INSERT INTO Products {cols} VALUES (" + ", ".join(vals) + ");") + elif table == 'employees': + cols = '(EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive)' + for r in rows: + birth = _fmt_str(r['birth'].strftime('%Y-%m-%d')) if dialect != 'oracle' else f"TO_DATE({_fmt_str(r['birth'].strftime('%Y-%m-%d'))}, 'YYYY-MM-DD')" + hire = _fmt_str(r['hire'].strftime('%Y-%m-%d')) if dialect != 'oracle' else f"TO_DATE({_fmt_str(r['hire'].strftime('%Y-%m-%d'))}, 'YYYY-MM-DD')" + vals = [ + _fmt_str(r['code']), _fmt_str(r['first']), _fmt_str(r['last']), _fmt_str(r['title']), + birth, hire, _fmt_str(r['email']), _fmt_str(r['phone']), _fmt_str(r['dept']), f"{r['salary']:.2f}", + 'NULL' if r['reports'] is None else str(r['reports']), _fmt_bool(dialect, r['active']) + ] + lines.append(f"INSERT INTO Employees {cols} VALUES (" + ", ".join(vals) + ");") + elif table == 'orders': + cols = '(OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes)' + for r in rows: + order_dt = _fmt_datetime(dialect, r['order_date']) + req_dt = _fmt_datetime(dialect, r['required_date']) + ship_dt = 'NULL' if r['shipped_date'] is None else _fmt_datetime(dialect, r['shipped_date']) + vals = [ + _fmt_str(r['number']), str(r['customer_id']), order_dt, req_dt, ship_dt, + _fmt_str(r['status']), f"{r['subtotal']:.2f}", f"{r['tax']:.2f}", f"{r['total']:.2f}", + _fmt_str(r['pay_method']), _fmt_str(r['pay_status']), str(r['emp_id']), 'NULL' + ] + lines.append(f"INSERT INTO Orders {cols} VALUES (" + ", ".join(vals) + ");") + elif table == 'orderdetails': + cols = '(OrderID, ProductID, UnitPrice, Quantity, Discount)' + for r in rows: + vals = [str(r['order_id']), str(r['product_id']), f"{r['unit_price']:.2f}", str(r['qty']), f"{r['discount']:.2f}"] + lines.append(f"INSERT INTO OrderDetails {cols} VALUES (" + ", ".join(vals) + ");") + return lines + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--dialect', '--db', dest='dialect', choices=['mssql','mysql','postgresql','oracle','sqlite'], default='mssql') + parser.add_argument('--tables', default='customers,products,employees,orders,orderdetails') + parser.add_argument('--rows', type=int, default=100) + parser.add_argument('--output', default='') + args = parser.parse_args() + + # Normalize dialect (accept common synonyms via --db/--dialect) + alias_map = { + 'postgres': 'postgresql', 'pg': 'postgresql', + 'maria': 'mysql', 'mariadb': 'mysql' + } + dialect = alias_map.get(args.dialect.lower(), args.dialect.lower()) + tables = [t.strip().lower() for t in args.tables.split(',') if t.strip()] + rows = args.rows + + customers = gen_customers(rows) + products = gen_products(rows) + employees = gen_employees(min(100, max(10, rows//2))) + orders = gen_orders(min(100, rows), len(customers), len(employees)) + orderdetails = gen_order_details(rows*2, len(orders), len(products)) + + all_lines = [] + if 'customers' in tables: + all_lines.append(f"-- Customers ({len(customers)} records)") + all_lines.extend(render_inserts(dialect, 'customers', customers)) + if 'products' in tables: + all_lines.append(f"-- Products ({len(products)} records)") + all_lines.extend(render_inserts(dialect, 'products', products)) + if 'employees' in tables: + all_lines.append(f"-- Employees ({len(employees)} records)") + all_lines.extend(render_inserts(dialect, 'employees', employees)) + if 'orders' in tables: + all_lines.append(f"-- Orders ({len(orders)} records)") + all_lines.extend(render_inserts(dialect, 'orders', orders)) + if 'orderdetails' in tables: + all_lines.append(f"-- OrderDetails ({len(orderdetails)} records)") + all_lines.extend(render_inserts(dialect, 'orderdetails', orderdetails)) + + output = "\n".join(all_lines) + "\n" + out_path = args.output + if not out_path: + script_dir = os.path.dirname(__file__) + out_path = os.path.join(script_dir, f"sample_data_{dialect}.sql") + with open(out_path, 'w', encoding='utf-8') as f: + f.write(output) + sys.stdout.write(out_path + "\n") if __name__ == "__main__": - print("-- Customers (100 records)") - print("INSERT INTO dbo.Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES") - print(generate_mssql_customers()) - print("GO\n") + main() From f8709cd780c9c8e5b1e39e0f9891901c525a831b Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Tue, 4 Nov 2025 22:30:20 +0900 Subject: [PATCH 12/25] Added oracle to support databases --- config/dbinfo.json | 6 +- package-lock.json | 15 +- queries/queries-sample-orders.json | 2 +- queries/queries-sample-orders.xml | 30 +- resources/sample_data_oracle.sql | 555 +++++++++++++++++++++++++++++ resources/sample_data_sqlite.sql | 555 +++++++++++++++++++++++++++++ 6 files changed, 1142 insertions(+), 21 deletions(-) create mode 100644 resources/sample_data_oracle.sql create mode 100644 resources/sample_data_sqlite.sql diff --git a/config/dbinfo.json b/config/dbinfo.json index da5f894..40094fd 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -78,11 +78,11 @@ }, "oracleDB": { "type": "oracle", - "user": "system", - "password": "oracle", + "user": "c##scott", + "password": "tiger", "server": "localhost", "port": 1521, - "serviceName": "XEPDB1", + "serviceName": "xe", "options": { "poolMin": 0, "poolMax": 4, diff --git a/package-lock.json b/package-lock.json index ad6771c..ded46c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,19 @@ { "name": "sql2excel", - "version": "1.3.1", + "version": "1.3.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql2excel", - "version": "1.3.1", + "version": "1.3.3", "dependencies": { "better-sqlite3": "^11.10.0", "exceljs": "^4.3.0", "json5": "^2.2.3", "mssql": "^10.0.0", "mysql2": "^3.4.0", + "oracledb": "^6.6.0", "pg": "^8.16.3", "xml2js": "^0.6.2", "yargs": "^17.7.2" @@ -3310,6 +3311,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oracledb": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/oracledb/-/oracledb-6.10.0.tgz", + "integrity": "sha512-kGUumXmrEWbSpBuKJyb9Ip3rXcNgKK6grunI3/cLPzrRvboZ6ZoLi9JQ+z6M/RIG924tY8BLflihL4CKKQAYMA==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR UPL-1.0)", + "engines": { + "node": ">=14.17" + } + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", diff --git a/queries/queries-sample-orders.json b/queries/queries-sample-orders.json index 7801c33..0030409 100644 --- a/queries/queries-sample-orders.json +++ b/queries/queries-sample-orders.json @@ -1,6 +1,6 @@ { "excel": { - "db": "sampleDB", + "db": "oracleDB", "output": "output/sales_summary_2024.xlsx", "maxRows": 1500, "header": { diff --git a/queries/queries-sample-orders.xml b/queries/queries-sample-orders.xml index 66a011b..0695307 100644 --- a/queries/queries-sample-orders.xml +++ b/queries/queries-sample-orders.xml @@ -1,5 +1,5 @@ - + @@ -22,7 +22,7 @@ PaymentStatus as PaymentStatus, FORMAT(TotalAmount, 'N0') as TotalAmount, PaymentMethod as PaymentMethod - FROM SampleDB.dbo.Orders + FROM Orders WHERE OrderDate >= '${startDate}' AND OrderDate <= '${endDate}' ORDER BY OrderDate DESC ]]> @@ -30,7 +30,7 @@ @@ -42,9 +42,9 @@ FORMAT(od.UnitPrice, 'N0') as UnitPrice, od.Quantity as Quantity, FORMAT(od.LineTotal, 'N0') as LineTotal - FROM SampleDB.dbo.Orders o - INNER JOIN SampleDB.dbo.Customers c ON o.CustomerID = c.CustomerID - INNER JOIN SampleDB.dbo.OrderDetails od ON o.OrderID = od.OrderID + FROM Orders o + INNER JOIN Customers c ON o.CustomerID = c.CustomerID + INNER JOIN OrderDetails od ON o.OrderID = od.OrderID WHERE o.OrderDate >= '${startDate}' AND o.OrderDate <= '${endDate}' ORDER BY o.OrderDate DESC ]]> @@ -52,9 +52,9 @@ = '${startDate}' AND o.OrderDate <= '${endDate}' ORDER BY o.OrderDate DESC ]]> @@ -62,9 +62,9 @@ = '${startDate}' AND o.OrderDate <= '${endDate}' ORDER BY o.OrderDate DESC ]]> @@ -72,7 +72,7 @@ = '${startDate}' AND OrderDate <= '${endDate}' AND OrderStatus IN (${statusList}) @@ -82,8 +82,8 @@ Date: Tue, 4 Nov 2025 22:40:29 +0900 Subject: [PATCH 13/25] Removed unnecessary queries --- resources/insert_sample_data.sql | 120 ---- resources/insert_sample_data_100_preview.sql | 0 resources/insert_sample_data_mysql.sql | 126 ----- resources/insert_sample_data_oracle.sql | 45 -- resources/insert_sample_data_postgresql.sql | 123 ---- resources/insert_sample_data_sqlite.sql | 123 ---- resources/sample_data_oracle.sql | 555 ------------------- resources/sample_data_sqlite.sql | 555 ------------------- 8 files changed, 1647 deletions(-) delete mode 100644 resources/insert_sample_data.sql delete mode 100644 resources/insert_sample_data_100_preview.sql delete mode 100644 resources/insert_sample_data_mysql.sql delete mode 100644 resources/insert_sample_data_oracle.sql delete mode 100644 resources/insert_sample_data_postgresql.sql delete mode 100644 resources/insert_sample_data_sqlite.sql delete mode 100644 resources/sample_data_oracle.sql delete mode 100644 resources/sample_data_sqlite.sql diff --git a/resources/insert_sample_data.sql b/resources/insert_sample_data.sql deleted file mode 100644 index 4ef62a8..0000000 --- a/resources/insert_sample_data.sql +++ /dev/null @@ -1,120 +0,0 @@ --- ======================================== --- 샘플 데이터 입력 스크립트 --- Microsoft SQL Server용 --- 100건 샘플 데이터 (한글 50건 + 영어 50건) --- ======================================== - -USE [SampleDB] -GO - --- ======================================== --- 1. Customers 테이블 데이터 입력 (100건) --- ======================================== - --- 한글 고객 (50건) -INSERT INTO dbo.Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES -('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, 1), -('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, 1), -('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, 1), -('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, 1), -('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, 1), -('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, 1), -('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, 1), -('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, 1), -('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, 1), -('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, 1), -('CUST011', '서울가구', '김영수', 'kim.ys@seoul-furniture.com', '02-1111-2222', '서울시 종로구 종로 100', '서울', '서울', '대한민국', 'Regular', 28000000.00, 1), -('CUST012', '부산수산', '이순희', 'lee.sh@busan-fish.com', '051-2222-3333', '부산시 남구 용호로 200', '부산', '부산', '대한민국', 'Premium', 45000000.00, 1), -('CUST013', '대구한방약품', '박건호', 'park.kh@daegu-herb.com', '053-3333-4444', '대구시 북구 칠성로 300', '대구', '대구', '대한민국', 'Regular', 32000000.00, 1), -('CUST014', '인천해운', '최미영', 'choi.my@incheon-ship.com', '032-4444-5555', '인천시 중구 항동 400', '인천', '인천', '대한민국', 'VIP', 95000000.00, 1), -('CUST015', '광주자동차부품', '정태윤', 'jung.ty@gwangju-auto.com', '062-5555-6666', '광주시 북구 첨단로 500', '광주', '광주', '대한민국', 'Premium', 55000000.00, 1), -('CUST016', '제주관광개발', '강민석', 'kang.ms@jeju-tour.com', '064-6666-7777', '제주시 노형동 600', '제주', '제주', '대한민국', 'Regular', 38000000.00, 1), -('CUST017', '울산조선', '윤혜진', 'yoon.hj@ulsan-ship.com', '052-7777-8888', '울산시 동구 방어진로 700', '울산', '울산', '대한민국', 'VIP', 120000000.00, 1), -('CUST018', '대전바이오', '임재현', 'lim.jh@daejeon-bio.com', '042-8888-9999', '대전시 서구 둔산로 800', '대전', '대전', '대한민국', 'Premium', 48000000.00, 1), -('CUST019', '경기반도체', '송현주', 'song.hj@gyeonggi-semi.com', '031-9999-0000', '경기도 화성시 동탄대로 900', '화성', '경기', '대한민국', 'VIP', 110000000.00, 1), -('CUST020', '서울패션', '한수연', 'han.sy@seoul-fashion.com', '02-1234-5670', '서울시 강남구 압구정로 1000', '서울', '서울', '대한민국', 'Regular', 26000000.00, 1), -('CUST021', '부산철강', '김동현', 'kim.dh@busan-steel.com', '051-2345-6780', '부산시 사상구 학장로 110', '부산', '부산', '대한민국', 'Premium', 52000000.00, 1), -('CUST022', '대구섬유공업', '이지은', 'lee.je@daegu-textile2.com', '053-3456-7890', '대구시 서구 염색공단 120', '대구', '대구', '대한민국', 'Regular', 29000000.00, 1), -('CUST023', '인천유리', '박상철', 'park.sc@incheon-glass.com', '032-4567-8900', '인천시 남동구 남동대로 130', '인천', '인천', '대한민국', 'Premium', 42000000.00, 1), -('CUST024', '광주전자부품', '최윤정', 'choi.yj@gwangju-elec.com', '062-5678-9010', '광주시 광산구 하남대로 140', '광주', '광주', '대한민국', 'Regular', 31000000.00, 1), -('CUST025', '제주식품', '정수현', 'jung.sh@jeju-food.com', '064-6789-0120', '제주시 애월읍 해안로 150', '제주', '제주', '대한민국', 'Regular', 24000000.00, 1), -('CUST026', '울산정유', '강태영', 'kang.ty@ulsan-oil.com', '052-7890-1230', '울산시 남구 여천로 160', '울산', '울산', '대한민국', 'VIP', 150000000.00, 1), -('CUST027', '대전전자', '윤미선', 'yoon.ms@daejeon-elec.com', '042-8901-2340', '대전시 대덕구 대덕대로 170', '대전', '대전', '대한민국', 'Premium', 58000000.00, 1), -('CUST028', '경기화학', '임경호', 'lim.kh@gyeonggi-chem.com', '031-9012-3450', '경기도 안산시 단원구 180', '안산', '경기', '대한민국', 'Premium', 65000000.00, 1), -('CUST029', '서울건설', '송재민', 'song.jm@seoul-const.com', '02-0123-4560', '서울시 서초구 서초대로 190', '서울', '서울', '대한민국', 'VIP', 130000000.00, 1), -('CUST030', '부산건설자재', '한영미', 'han.ym@busan-material.com', '051-1234-5670', '부산시 강서구 공항로 200', '부산', '부산', '대한민국', 'Regular', 33000000.00, 1), -('CUST031', '대구기계', '김민재', 'kim.mj@daegu-machine.com', '053-2345-6781', '대구시 달서구 성서로 210', '대구', '대구', '대한민국', 'Premium', 47000000.00, 1), -('CUST032', '인천항만', '이상훈', 'lee.sh@incheon-port.com', '032-3456-7892', '인천시 중구 항동7가 220', '인천', '인천', '대한민국', 'VIP', 140000000.00, 1), -('CUST033', '광주광산', '박정아', 'park.ja@gwangju-mine.com', '062-4567-8903', '광주시 북구 운암로 230', '광주', '광주', '대한민국', 'Regular', 27000000.00, 1), -('CUST034', '제주에너지', '최승현', 'choi.sh@jeju-energy.com', '064-5678-9014', '제주시 구좌읍 240', '제주', '제주', '대한민국', 'Premium', 72000000.00, 1), -('CUST035', '울산자동차', '정유진', 'jung.yj@ulsan-auto.com', '052-6789-0125', '울산시 북구 산업로 250', '울산', '울산', '대한민국', 'VIP', 160000000.00, 1), -('CUST036', '대전소프트웨어', '강도현', 'kang.dh@daejeon-sw.com', '042-7890-1236', '대전시 유성구 테크노 260', '대전', '대전', '대한민국', 'Premium', 54000000.00, 1), -('CUST037', '경기물류', '윤서준', 'yoon.sj@gyeonggi-logis.com', '031-8901-2347', '경기도 이천시 270', '이천', '경기', '대한민국', 'Regular', 36000000.00, 1), -('CUST038', '서울의료기기', '임하은', 'lim.he@seoul-medical.com', '02-9012-3458', '서울시 금천구 가산디지털 280', '서울', '서울', '대한민국', 'Premium', 68000000.00, 1), -('CUST039', '부산바이오', '송지우', 'song.jw@busan-bio.com', '051-0123-4569', '부산시 기장군 정관읍 290', '부산', '부산', '대한민국', 'Premium', 71000000.00, 1), -('CUST040', '대구IT', '한승우', 'han.sw@daegu-it.com', '053-1234-5672', '대구시 수성구 알파시티 300', '대구', '대구', '대한민국', 'Regular', 39000000.00, 1), -('CUST041', '인천신재생에너지', '김시우', 'kim.sw@incheon-green.com', '032-2345-6783', '인천시 서구 가좌동 310', '인천', '인천', '대한민국', 'VIP', 125000000.00, 1), -('CUST042', '광주스마트팩토리', '이예은', 'lee.ye@gwangju-smart.com', '062-3456-7894', '광주시 남구 봉선로 320', '광주', '광주', '대한민국', 'Premium', 62000000.00, 1), -('CUST043', '제주데이터센터', '박하준', 'park.hj@jeju-data.com', '064-4567-8905', '제주시 첨단과학로 330', '제주', '제주', '대한민국', 'Premium', 78000000.00, 1), -('CUST044', '울산디스플레이', '최서윤', 'choi.sy@ulsan-display.com', '052-5678-9016', '울산시 중구 성남동 340', '울산', '울산', '대한민국', 'VIP', 135000000.00, 1), -('CUST045', '대전우주항공', '정민재', 'jung.mj@daejeon-aero.com', '042-6789-0127', '대전시 유성구 대덕대로 350', '대전', '대전', '대한민국', 'Premium', 88000000.00, 1), -('CUST046', '경기AI산업', '강유나', 'kang.yn@gyeonggi-ai.com', '031-7890-1238', '경기도 성남시 분당구 360', '성남', '경기', '대한민국', 'VIP', 145000000.00, 1), -('CUST047', '서울핀테크', '윤도윤', 'yoon.dy@seoul-fintech.com', '02-8901-2349', '서울시 영등포구 여의도 370', '서울', '서울', '대한민국', 'Premium', 92000000.00, 1), -('CUST048', '부산로봇산업', '임서준', 'lim.sj@busan-robot.com', '051-9012-3460', '부산시 강서구 미음산단 380', '부산', '부산', '대한민국', 'Regular', 41000000.00, 1), -('CUST049', '대구드론', '송지안', 'song.ja@daegu-drone.com', '053-0123-4571', '대구시 동구 신서동 390', '대구', '대구', '대한민국', 'Premium', 56000000.00, 1), -('CUST050', '인천스마트시티', '한예진', 'han.yj@incheon-smart.com', '032-1234-5674', '인천시 연수구 송도국제 400', '인천', '인천', '대한민국', 'VIP', 170000000.00, 1), - --- 영어 고객 (50건) -('CUST051', 'Tech Solutions Inc', 'John Smith', 'john@techsolutions.com', '+1-555-0101', '123 Silicon Valley Blvd', 'San Francisco', 'CA', 'USA', 'Premium', 75000000.00, 1), -('CUST052', 'Global Trading Co', 'Emily Johnson', 'emily@globaltrading.com', '+1-555-0102', '456 Wall Street', 'New York', 'NY', 'USA', 'VIP', 120000000.00, 1), -('CUST053', 'Digital Innovations', 'Michael Brown', 'michael@digitalinov.com', '+44-20-7123', '789 Oxford Street', 'London', 'England', 'UK', 'Regular', 45000000.00, 1), -('CUST054', 'Advanced Manufacturing', 'Sarah Davis', 'sarah@advmanu.com', '+49-30-1234', '321 Hauptstraße', 'Berlin', 'Berlin', 'Germany', 'Premium', 82000000.00, 1), -('CUST055', 'Pacific Logistics', 'David Wilson', 'david@pacificlog.com', '+61-2-5678', '654 Harbor Road', 'Sydney', 'NSW', 'Australia', 'VIP', 135000000.00, 1), -('CUST056', 'Euro Electronics', 'Sophie Martin', 'sophie@euroelec.com', '+33-1-2345', '987 Champs-Élysées', 'Paris', 'IDF', 'France', 'Regular', 38000000.00, 1), -('CUST057', 'Asia Pacific Trade', 'James Lee', 'james@apacific.com', '+65-6789-0123', '147 Orchard Road', 'Singapore', 'Singapore', 'Singapore', 'Premium', 95000000.00, 1), -('CUST058', 'Northern Industries', 'Emma Anderson', 'emma@northind.com', '+46-8-5678', '258 Drottninggatan', 'Stockholm', 'Stockholm', 'Sweden', 'Regular', 52000000.00, 1), -('CUST059', 'Smart Tech Corp', 'Oliver Taylor', 'oliver@smarttech.com', '+1-555-0103', '369 Tech Park Drive', 'Austin', 'TX', 'USA', 'VIP', 148000000.00, 1), -('CUST060', 'International Supply', 'Isabella Thomas', 'isabella@intsupply.com', '+1-416-789-0', '741 Bay Street', 'Toronto', 'ON', 'Canada', 'Premium', 67000000.00, 1), -('CUST061', 'Future Systems', 'William Jackson', 'william@futuresys.com', '+81-3-1234', '852 Shibuya', 'Tokyo', 'Tokyo', 'Japan', 'VIP', 158000000.00, 1), -('CUST062', 'Green Energy Ltd', 'Olivia White', 'olivia@greenenergy.com', '+44-161-234', '963 Market Street', 'Manchester', 'England', 'UK', 'Regular', 43000000.00, 1), -('CUST063', 'Advanced Materials', 'Ethan Harris', 'ethan@advmaterials.com', '+49-89-5678', '159 Marienplatz', 'Munich', 'Bavaria', 'Germany', 'Premium', 78000000.00, 1), -('CUST064', 'Ocean Freight Co', 'Ava Martinez', 'ava@oceanfreight.com', '+31-20-1234', '357 Damrak', 'Amsterdam', 'NH', 'Netherlands', 'VIP', 142000000.00, 1), -('CUST065', 'Digital Commerce', 'Noah Robinson', 'noah@digicommerce.com', '+1-555-0104', '753 Commerce Street', 'Seattle', 'WA', 'USA', 'Premium', 89000000.00, 1), -('CUST066', 'Biotech Research', 'Mia Clark', 'mia@biotech.com', '+41-44-789', '951 Bahnhofstrasse', 'Zurich', 'ZH', 'Switzerland', 'VIP', 165000000.00, 1), -('CUST067', 'Automotive Parts Ltd', 'Lucas Rodriguez', 'lucas@autoparts.com', '+39-02-3456', '246 Via Montenapoleone', 'Milan', 'Lombardy', 'Italy', 'Regular', 48000000.00, 1), -('CUST068', 'Cloud Services Inc', 'Charlotte Lewis', 'charlotte@cloudserv.com', '+353-1-234', '468 OConnell Street', 'Dublin', 'Dublin', 'Ireland', 'Premium', 72000000.00, 1), -('CUST069', 'Pharma Solutions', 'Benjamin Walker', 'benjamin@pharmasol.com', '+32-2-5678', '579 Grand Place', 'Brussels', 'Brussels', 'Belgium', 'VIP', 128000000.00, 1), -('CUST070', 'Robotics International', 'Amelia Hall', 'amelia@robotics.com', '+82-2-1234', '681 Gangnam-gu', 'Seoul', 'Seoul', 'South Korea', 'Premium', 94000000.00, 1), -('CUST071', 'Financial Systems', 'Henry Allen', 'henry@finsys.com', '+1-555-0105', '792 Financial District', 'Chicago', 'IL', 'USA', 'VIP', 156000000.00, 1), -('CUST072', 'Renewable Power', 'Harper Young', 'harper@renewpower.com', '+45-33-1234', '813 Nyhavn', 'Copenhagen', 'Capital', 'Denmark', 'Regular', 51000000.00, 1), -('CUST073', 'Aerospace Tech', 'Alexander King', 'alex@aerotech.com', '+1-555-0106', '924 Aerospace Parkway', 'Houston', 'TX', 'USA', 'VIP', 175000000.00, 1), -('CUST074', 'Smart Agriculture', 'Evelyn Wright', 'evelyn@smartagri.com', '+31-10-5678', '135 Coolsingel', 'Rotterdam', 'ZH', 'Netherlands', 'Premium', 63000000.00, 1), -('CUST075', 'Quantum Computing', 'Sebastian Lopez', 'sebastian@quantum.com', '+1-555-0107', '246 Innovation Way', 'Boston', 'MA', 'USA', 'VIP', 182000000.00, 1), -('CUST076', 'Marine Solutions', 'Ella Hill', 'ella@marinesol.com', '+47-22-1234', '357 Stortorget', 'Oslo', 'Oslo', 'Norway', 'Regular', 46000000.00, 1), -('CUST077', 'AI Development', 'Jack Scott', 'jack@aidev.com', '+1-555-0108', '468 Tech Center', 'San Jose', 'CA', 'USA', 'Premium', 98000000.00, 1), -('CUST078', 'Logistics Solutions', 'Aria Green', 'aria@logisol.com', '+65-6234-5678', '579 Business Park', 'Singapore', 'Singapore', 'Singapore', 'VIP', 138000000.00, 1), -('CUST079', 'Construction Tech', 'Mason Adams', 'mason@constructech.com', '+61-3-1234', '691 Collins Street', 'Melbourne', 'VIC', 'Australia', 'Premium', 71000000.00, 1), -('CUST080', 'Food Processing', 'Luna Baker', 'luna@foodproc.com', '+34-91-234', '702 Gran Via', 'Madrid', 'Madrid', 'Spain', 'Regular', 42000000.00, 1), -('CUST081', 'Textile Manufacturing', 'Logan Nelson', 'logan@textilema.com', '+91-22-1234', '813 Marine Drive', 'Mumbai', 'MH', 'India', 'Premium', 54000000.00, 1), -('CUST082', 'Chemical Industries', 'Layla Carter', 'layla@chemind.com', '+55-11-5678', '924 Avenida Paulista', 'São Paulo', 'SP', 'Brazil', 'VIP', 132000000.00, 1), -('CUST083', 'Mining Corporation', 'Elijah Mitchell', 'elijah@miningcorp.com', '+27-11-234', '135 Commissioner St', 'Johannesburg', 'GP', 'South Africa', 'Premium', 87000000.00, 1), -('CUST084', 'Healthcare Systems', 'Chloe Perez', 'chloe@healthcare.com', '+1-555-0109', '246 Medical Center', 'Philadelphia', 'PA', 'USA', 'VIP', 149000000.00, 1), -('CUST085', 'Education Technology', 'Matthew Roberts', 'matthew@edutech.com', '+44-131-234', '357 Royal Mile', 'Edinburgh', 'Scotland', 'UK', 'Regular', 39000000.00, 1), -('CUST086', 'Entertainment Media', 'Avery Turner', 'avery@entmedia.com', '+1-555-0110', '468 Sunset Boulevard', 'Los Angeles', 'CA', 'USA', 'Premium', 76000000.00, 1), -('CUST087', 'Security Solutions', 'Daniel Phillips', 'daniel@secsol.com', '+972-3-1234', '579 Rothschild Blvd', 'Tel Aviv', 'TA', 'Israel', 'VIP', 124000000.00, 1), -('CUST088', 'Environmental Tech', 'Sofia Campbell', 'sofia@envtech.com', '+358-9-1234', '691 Esplanadi', 'Helsinki', 'Uusimaa', 'Finland', 'Premium', 69000000.00, 1), -('CUST089', 'Transportation Systems', 'Joseph Parker', 'joseph@transys.com', '+43-1-5678', '702 Ringstraße', 'Vienna', 'Vienna', 'Austria', 'Regular', 57000000.00, 1), -('CUST090', 'Telecommunications', 'Victoria Evans', 'victoria@telecom.com', '+852-2345-6789', '813 Nathan Road', 'Hong Kong', 'HK', 'Hong Kong', 'VIP', 167000000.00, 1), -('CUST091', 'Water Treatment', 'David Edwards', 'david@watertreat.com', '+971-4-1234', '924 Sheikh Zayed Rd', 'Dubai', 'Dubai', 'UAE', 'Premium', 102000000.00, 1), -('CUST092', 'Fashion Design', 'Grace Collins', 'grace@fashiondes.com', '+33-1-5678', '135 Rue de Rivoli', 'Paris', 'IDF', 'France', 'Regular', 44000000.00, 1), -('CUST093', 'Gaming Studios', 'Samuel Stewart', 'samuel@gamingstudios.com', '+1-555-0111', '246 Game Avenue', 'San Francisco', 'CA', 'USA', 'Premium', 91000000.00, 1), -('CUST094', 'Space Technology', 'Zoe Sanchez', 'zoe@spacetech.com', '+1-321-555-0112', '357 Kennedy Space Center', 'Cape Canaveral', 'FL', 'USA', 'VIP', 195000000.00, 1), -('CUST095', 'Furniture Design', 'Ryan Morris', 'ryan@furndes.com', '+46-31-1234', '468 Avenyn', 'Gothenburg', 'VG', 'Sweden', 'Regular', 49000000.00, 1), -('CUST096', 'Printing Services', 'Penelope Rogers', 'penelope@printserv.com', '+49-40-5678', '579 Jungfernstieg', 'Hamburg', 'Hamburg', 'Germany', 'Premium', 58000000.00, 1), -('CUST097', 'Packaging Solutions', 'Isaac Reed', 'isaac@packsol.com', '+1-555-0113', '691 Industrial Pkwy', 'Atlanta', 'GA', 'USA', 'VIP', 118000000.00, 1), -('CUST098', 'Laboratory Equipment', 'Stella Cook', 'stella@labequip.com', '+41-61-1234', '702 Basel Street', 'Basel', 'BS', 'Switzerland', 'Premium', 84000000.00, 1), -('CUST099', 'Sports Equipment', 'Christian Morgan', 'christian@sportseq.com', '+1-555-0114', '813 Sports Complex', 'Denver', 'CO', 'USA', 'Regular', 53000000.00, 1), -('CUST100', 'Defense Systems', 'Nora Bell', 'nora@defensesys.com', '+1-703-555-0115', '924 Pentagon Road', 'Arlington', 'VA', 'USA', 'VIP', 220000000.00, 1) -GO - --- (계속...) diff --git a/resources/insert_sample_data_100_preview.sql b/resources/insert_sample_data_100_preview.sql deleted file mode 100644 index e69de29..0000000 diff --git a/resources/insert_sample_data_mysql.sql b/resources/insert_sample_data_mysql.sql deleted file mode 100644 index b4d338a..0000000 --- a/resources/insert_sample_data_mysql.sql +++ /dev/null @@ -1,126 +0,0 @@ --- ======================================== --- 샘플 데이터 입력 스크립트 --- MySQL / MariaDB용 --- ======================================== - -USE sampledb; - --- ======================================== --- 1. Customers 테이블 데이터 입력 --- ======================================== - -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES -('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, TRUE), -('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, TRUE), -('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, TRUE), -('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, TRUE), -('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, TRUE), -('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, TRUE), -('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, TRUE), -('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, TRUE), -('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, TRUE), -('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, TRUE); - --- ======================================== --- 2. Products 테이블 데이터 입력 --- ======================================== - -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES -('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, FALSE, '고성능 업무용 노트북'), -('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, FALSE, '인체공학적 디자인 무선 마우스'), -('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, FALSE, 'RGB 백라이트 기계식 키보드'), -('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, FALSE, '4K UHD 해상도 모니터'), -('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, FALSE, '초고속 데이터 전송 외장 SSD'), -('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, FALSE, 'USB 3.0 고속 메모리'), -('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, FALSE, '노이즈 캔슬링 기능'), -('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, FALSE, '방수 기능 휴대용 스피커'), -('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, FALSE, '1080p 화상회의용 웹캠'), -('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, FALSE, '안드로이드 태블릿'), -('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, FALSE, '흑백 레이저 프린터'), -('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, FALSE, '프린터/스캐너/복사기 일체형'), -('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, FALSE, 'LED 조명 각도조절 가능'), -('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, FALSE, '인체공학 메쉬 의자'), -('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, FALSE, '4단 서류 보관함'); - --- ======================================== --- 3. Employees 테이블 데이터 입력 --- ======================================== - -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES -('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, TRUE), -('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, TRUE), -('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, TRUE), -('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, TRUE), -('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, TRUE), -('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, TRUE), -('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, TRUE), -('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, TRUE), -('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, TRUE), -('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, TRUE); - --- ======================================== --- 4. Orders 테이블 데이터 입력 --- ======================================== - -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES -('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), -('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), -('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), -('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), -('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), -('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), -('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), -('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); - --- ======================================== --- 5. OrderDetails 테이블 데이터 입력 --- ======================================== - -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES --- Order 1 -(1, 1, 1500000.00, 2, 5.00), --- Order 2 -(2, 2, 35000.00, 10, 0.00), -(2, 3, 120000.00, 5, 0.00), -(2, 6, 25000.00, 20, 0.00), --- Order 3 -(3, 4, 450000.00, 3, 5.00), -(3, 5, 180000.00, 2, 5.00), --- Order 4 -(4, 1, 1500000.00, 2, 10.00), -(4, 4, 450000.00, 2, 10.00), -(4, 7, 150000.00, 5, 10.00), --- Order 5 -(5, 8, 80000.00, 10, 5.00), -(5, 9, 95000.00, 5, 5.00), -(5, 10, 450000.00, 1, 5.00), --- Order 6 -(6, 11, 350000.00, 5, 5.00), -(6, 13, 45000.00, 20, 5.00), --- Order 7 -(7, 12, 650000.00, 3, 10.00), -(7, 14, 250000.00, 10, 10.00), --- Order 8 -(8, 15, 180000.00, 5, 0.00), -(8, 2, 35000.00, 10, 0.00), --- Order 9 -(9, 6, 25000.00, 30, 0.00), -(9, 13, 45000.00, 5, 0.00), --- Order 10 -(10, 1, 1500000.00, 1, 5.00), -(10, 7, 150000.00, 5, 5.00); - --- ======================================== --- 완료 메시지 --- ======================================== - -SELECT 'Sample data inserted successfully for MySQL/MariaDB!' AS Message; -SELECT - 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers -UNION ALL SELECT 'Products', COUNT(*) FROM Products -UNION ALL SELECT 'Employees', COUNT(*) FROM Employees -UNION ALL SELECT 'Orders', COUNT(*) FROM Orders -UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; - diff --git a/resources/insert_sample_data_oracle.sql b/resources/insert_sample_data_oracle.sql deleted file mode 100644 index a98a444..0000000 --- a/resources/insert_sample_data_oracle.sql +++ /dev/null @@ -1,45 +0,0 @@ --- ======================================== --- 샘플 데이터 입력 스크립트 (Oracle) --- ======================================== - --- Customers -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) -VALUES ('CUST001','Acme Corp','John Doe','john@acme.com','+1-555-1001','New York','NY','USA','Regular',10000,1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) -VALUES ('CUST002','Globex','Jane Smith','jane@globex.com','+1-555-1002','Los Angeles','CA','USA','VIP',20000,1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, City, Region, Country, CustomerType, CreditLimit, IsActive) -VALUES ('CUST003','Initech','Bob Martin','bob@initech.com','+1-555-1003','Seattle','WA','USA','Regular',15000,1); - --- Products -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) -VALUES ('P-100','Laptop 14"','Electronics',1200,50); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) -VALUES ('P-101','Wireless Mouse','Electronics',25,500); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock) -VALUES ('P-102','Office Chair','Furniture',180,120); - --- Employees -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) -VALUES ('E-001','Alice','Kim','Manager','Sales',6500,1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) -VALUES ('E-002','Brian','Lee','Engineer','IT',7200,1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, Department, Salary, IsActive) -VALUES ('E-003','Cathy','Park','Analyst','Finance',5800,1); - --- Orders -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentStatus) -VALUES ('SO-20240101-001', 1, TO_TIMESTAMP('2024-01-01 10:00:00','YYYY-MM-DD HH24:MI:SS'), 'Pending', 1225, 122.5, 1347.5, 'Unpaid'); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentStatus) -VALUES ('SO-20240105-002', 2, TO_TIMESTAMP('2024-01-05 15:30:00','YYYY-MM-DD HH24:MI:SS'), 'Shipped', 180, 18, 198, 'Paid'); - --- OrderDetails -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) -VALUES (1, 1, 1200, 1, 0); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) -VALUES (1, 2, 25, 1, 0); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) -VALUES (2, 3, 180, 1, 0); - -COMMIT; - -PROMPT 'Oracle용 샘플 데이터 입력 완료' diff --git a/resources/insert_sample_data_postgresql.sql b/resources/insert_sample_data_postgresql.sql deleted file mode 100644 index fbc8d24..0000000 --- a/resources/insert_sample_data_postgresql.sql +++ /dev/null @@ -1,123 +0,0 @@ --- ======================================== --- 샘플 데이터 입력 스크립트 --- PostgreSQL용 --- ======================================== - --- ======================================== --- 1. Customers 테이블 데이터 입력 --- ======================================== - -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES -('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, TRUE), -('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, TRUE), -('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, TRUE), -('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, TRUE), -('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, TRUE), -('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, TRUE), -('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, TRUE), -('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, TRUE), -('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, TRUE), -('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, TRUE); - --- ======================================== --- 2. Products 테이블 데이터 입력 --- ======================================== - -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES -('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, FALSE, '고성능 업무용 노트북'), -('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, FALSE, '인체공학적 디자인 무선 마우스'), -('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, FALSE, 'RGB 백라이트 기계식 키보드'), -('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, FALSE, '4K UHD 해상도 모니터'), -('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, FALSE, '초고속 데이터 전송 외장 SSD'), -('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, FALSE, 'USB 3.0 고속 메모리'), -('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, FALSE, '노이즈 캔슬링 기능'), -('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, FALSE, '방수 기능 휴대용 스피커'), -('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, FALSE, '1080p 화상회의용 웹캠'), -('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, FALSE, '안드로이드 태블릿'), -('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, FALSE, '흑백 레이저 프린터'), -('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, FALSE, '프린터/스캐너/복사기 일체형'), -('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, FALSE, 'LED 조명 각도조절 가능'), -('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, FALSE, '인체공학 메쉬 의자'), -('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, FALSE, '4단 서류 보관함'); - --- ======================================== --- 3. Employees 테이블 데이터 입력 --- ======================================== - -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES -('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, TRUE), -('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, TRUE), -('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, TRUE), -('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, TRUE), -('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, TRUE), -('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, TRUE), -('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, TRUE), -('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, TRUE), -('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, TRUE), -('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, TRUE); - --- ======================================== --- 4. Orders 테이블 데이터 입력 --- ======================================== - -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES -('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), -('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), -('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), -('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), -('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), -('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), -('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), -('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); - --- ======================================== --- 5. OrderDetails 테이블 데이터 입력 --- ======================================== - -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES --- Order 1 -(1, 1, 1500000.00, 2, 5.00), --- Order 2 -(2, 2, 35000.00, 10, 0.00), -(2, 3, 120000.00, 5, 0.00), -(2, 6, 25000.00, 20, 0.00), --- Order 3 -(3, 4, 450000.00, 3, 5.00), -(3, 5, 180000.00, 2, 5.00), --- Order 4 -(4, 1, 1500000.00, 2, 10.00), -(4, 4, 450000.00, 2, 10.00), -(4, 7, 150000.00, 5, 10.00), --- Order 5 -(5, 8, 80000.00, 10, 5.00), -(5, 9, 95000.00, 5, 5.00), -(5, 10, 450000.00, 1, 5.00), --- Order 6 -(6, 11, 350000.00, 5, 5.00), -(6, 13, 45000.00, 20, 5.00), --- Order 7 -(7, 12, 650000.00, 3, 10.00), -(7, 14, 250000.00, 10, 10.00), --- Order 8 -(8, 15, 180000.00, 5, 0.00), -(8, 2, 35000.00, 10, 0.00), --- Order 9 -(9, 6, 25000.00, 30, 0.00), -(9, 13, 45000.00, 5, 0.00), --- Order 10 -(10, 1, 1500000.00, 1, 5.00), -(10, 7, 150000.00, 5, 5.00); - --- ======================================== --- 완료 메시지 --- ======================================== - -SELECT 'Sample data inserted successfully for PostgreSQL!' AS Message; -SELECT 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers -UNION ALL SELECT 'Products', COUNT(*) FROM Products -UNION ALL SELECT 'Employees', COUNT(*) FROM Employees -UNION ALL SELECT 'Orders', COUNT(*) FROM Orders -UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; - diff --git a/resources/insert_sample_data_sqlite.sql b/resources/insert_sample_data_sqlite.sql deleted file mode 100644 index d3e7f83..0000000 --- a/resources/insert_sample_data_sqlite.sql +++ /dev/null @@ -1,123 +0,0 @@ --- ======================================== --- 샘플 데이터 입력 스크립트 --- SQLite용 --- ======================================== - --- ======================================== --- 1. Customers 테이블 데이터 입력 --- ======================================== - -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES -('CUST001', '(주)한국전자', '김철수', 'kim@hankook-elec.co.kr', '02-1234-5678', '서울시 강남구 테헤란로 123', '서울', '서울', '대한민국', 'Premium', 50000000.00, 1), -('CUST002', '서울무역상사', '이영희', 'lee@seoul-trade.com', '02-2345-6789', '서울시 중구 세종대로 456', '서울', '서울', '대한민국', 'Regular', 30000000.00, 1), -('CUST003', '부산산업(주)', '박민수', 'park@busan-ind.co.kr', '051-3456-7890', '부산시 해운대구 센텀로 789', '부산', '부산', '대한민국', 'Premium', 40000000.00, 1), -('CUST004', '대구섬유', '최지영', 'choi@daegu-textile.com', '053-4567-8901', '대구시 중구 동성로 234', '대구', '대구', '대한민국', 'Regular', 20000000.00, 1), -('CUST005', '인천물류센터', '정현우', 'jung@incheon-logis.com', '032-5678-9012', '인천시 연수구 송도대로 567', '인천', '인천', '대한민국', 'VIP', 100000000.00, 1), -('CUST006', '광주식품유통', '강수진', 'kang@gwangju-food.com', '062-6789-0123', '광주시 서구 상무대로 890', '광주', '광주', '대한민국', 'Regular', 25000000.00, 1), -('CUST007', '제주특산물', '윤서연', 'yoon@jeju-special.com', '064-7890-1234', '제주시 연동 중앙로 345', '제주', '제주', '대한민국', 'Regular', 15000000.00, 1), -('CUST008', '울산화학공업', '임동혁', 'lim@ulsan-chem.co.kr', '052-8901-2345', '울산시 남구 삼산로 678', '울산', '울산', '대한민국', 'Premium', 60000000.00, 1), -('CUST009', '대전기술연구소', '송미래', 'song@daejeon-tech.com', '042-9012-3456', '대전시 유성구 대학로 901', '대전', '대전', '대한민국', 'Regular', 35000000.00, 1), -('CUST010', '경기통상', '한지훈', 'han@gyeonggi-trade.com', '031-0123-4567', '경기도 수원시 영통구 광교로 123', '수원', '경기', '대한민국', 'VIP', 80000000.00, 1); - --- ======================================== --- 2. Products 테이블 데이터 입력 --- ======================================== - -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES -('PROD001', '노트북 컴퓨터 15인치', '전자제품', 1500000.00, 50, 0, 10, 0, '고성능 업무용 노트북'), -('PROD002', '무선 마우스', '전자제품', 35000.00, 200, 0, 50, 0, '인체공학적 디자인 무선 마우스'), -('PROD003', '기계식 키보드', '전자제품', 120000.00, 100, 0, 20, 0, 'RGB 백라이트 기계식 키보드'), -('PROD004', '27인치 모니터', '전자제품', 450000.00, 75, 10, 15, 0, '4K UHD 해상도 모니터'), -('PROD005', '외장 SSD 1TB', '저장장치', 180000.00, 150, 0, 30, 0, '초고속 데이터 전송 외장 SSD'), -('PROD006', 'USB 메모리 64GB', '저장장치', 25000.00, 500, 0, 100, 0, 'USB 3.0 고속 메모리'), -('PROD007', '무선 이어폰', '오디오', 150000.00, 120, 20, 25, 0, '노이즈 캔슬링 기능'), -('PROD008', '블루투스 스피커', '오디오', 80000.00, 90, 0, 20, 0, '방수 기능 휴대용 스피커'), -('PROD009', '웹캠 FHD', '전자제품', 95000.00, 60, 10, 15, 0, '1080p 화상회의용 웹캠'), -('PROD010', '태블릿 10인치', '전자제품', 450000.00, 40, 10, 10, 0, '안드로이드 태블릿'), -('PROD011', '프린터 레이저', '사무기기', 350000.00, 30, 5, 8, 0, '흑백 레이저 프린터'), -('PROD012', '복합기 컬러', '사무기기', 650000.00, 20, 0, 5, 0, '프린터/스캐너/복사기 일체형'), -('PROD013', '책상 스탠드', '사무용품', 45000.00, 100, 0, 20, 0, 'LED 조명 각도조절 가능'), -('PROD014', '사무용 의자', '가구', 250000.00, 50, 10, 10, 0, '인체공학 메쉬 의자'), -('PROD015', '파일 캐비닛', '가구', 180000.00, 25, 0, 5, 0, '4단 서류 보관함'); - --- ======================================== --- 3. Employees 테이블 데이터 입력 --- ======================================== - -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES -('EMP001', '철수', '김', '사장', '1975-05-15', '2010-01-01', 'kim.cs@company.com', '010-1111-1111', '경영진', 100000000.00, NULL, 1), -('EMP002', '영희', '이', '부사장', '1978-08-20', '2012-03-15', 'lee.yh@company.com', '010-2222-2222', '경영진', 80000000.00, 1, 1), -('EMP003', '민수', '박', '영업이사', '1980-03-10', '2013-06-01', 'park.ms@company.com', '010-3333-3333', '영업부', 60000000.00, 2, 1), -('EMP004', '지영', '최', '마케팅이사', '1982-11-25', '2014-09-01', 'choi.jy@company.com', '010-4444-4444', '마케팅부', 55000000.00, 2, 1), -('EMP005', '현우', '정', '기술이사', '1981-07-08', '2013-04-15', 'jung.hw@company.com', '010-5555-5555', '기술부', 65000000.00, 2, 1), -('EMP006', '수진', '강', '영업팀장', '1985-02-14', '2015-01-10', 'kang.sj@company.com', '010-6666-6666', '영업부', 45000000.00, 3, 1), -('EMP007', '서연', '윤', '마케팅팀장', '1987-09-30', '2016-05-20', 'yoon.sy@company.com', '010-7777-7777', '마케팅부', 42000000.00, 4, 1), -('EMP008', '동혁', '임', '개발팀장', '1986-04-18', '2015-08-01', 'lim.dh@company.com', '010-8888-8888', '기술부', 50000000.00, 5, 1), -('EMP009', '미래', '송', '영업사원', '1990-12-05', '2018-03-10', 'song.mr@company.com', '010-9999-9999', '영업부', 35000000.00, 6, 1), -('EMP010', '지훈', '한', '개발자', '1992-06-22', '2019-07-15', 'han.jh@company.com', '010-0000-0000', '기술부', 40000000.00, 8, 1); - --- ======================================== --- 4. Orders 테이블 데이터 입력 --- ======================================== - -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, TotalAmount, DiscountAmount, TaxAmount, NetAmount, ShippingAddress) VALUES -('ORD-2024-001', 1, '2024-01-05 10:30:00', '2024-01-12 00:00:00', '2024-01-08 14:20:00', 'Shipped', 3000000.00, 150000.00, 285000.00, 3135000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-002', 2, '2024-01-08 14:15:00', '2024-01-15 00:00:00', '2024-01-10 11:30:00', 'Shipped', 1500000.00, 0.00, 150000.00, 1650000.00, '서울시 중구 세종대로 456'), -('ORD-2024-003', 3, '2024-01-10 09:00:00', '2024-01-17 00:00:00', '2024-01-12 16:45:00', 'Shipped', 2200000.00, 110000.00, 209000.00, 2299000.00, '부산시 해운대구 센텀로 789'), -('ORD-2024-004', 5, '2024-01-15 11:20:00', '2024-01-22 00:00:00', '2024-01-18 10:15:00', 'Shipped', 5000000.00, 500000.00, 450000.00, 4950000.00, '인천시 연수구 송도대로 567'), -('ORD-2024-005', 1, '2024-01-20 15:45:00', '2024-01-27 00:00:00', NULL, 'Processing', 1800000.00, 90000.00, 171000.00, 1881000.00, '서울시 강남구 테헤란로 123'), -('ORD-2024-006', 8, '2024-01-25 13:30:00', '2024-02-01 00:00:00', NULL, 'Pending', 3500000.00, 175000.00, 332500.00, 3657500.00, '울산시 남구 삼산로 678'), -('ORD-2024-007', 10, '2024-02-01 10:00:00', '2024-02-08 00:00:00', NULL, 'Pending', 4200000.00, 420000.00, 378000.00, 4158000.00, '경기도 수원시 영통구 광교로 123'), -('ORD-2024-008', 4, '2024-02-05 14:20:00', '2024-02-12 00:00:00', NULL, 'Pending', 1200000.00, 0.00, 120000.00, 1320000.00, '대구시 중구 동성로 234'), -('ORD-2024-009', 6, '2024-02-10 09:30:00', '2024-02-17 00:00:00', NULL, 'Pending', 950000.00, 0.00, 95000.00, 1045000.00, '광주시 서구 상무대로 890'), -('ORD-2024-010', 9, '2024-02-15 16:00:00', '2024-02-22 00:00:00', NULL, 'Pending', 2800000.00, 140000.00, 266000.00, 2926000.00, '대전시 유성구 대학로 901'); - --- ======================================== --- 5. OrderDetails 테이블 데이터 입력 --- ======================================== - -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES --- Order 1 -(1, 1, 1500000.00, 2, 5.00), --- Order 2 -(2, 2, 35000.00, 10, 0.00), -(2, 3, 120000.00, 5, 0.00), -(2, 6, 25000.00, 20, 0.00), --- Order 3 -(3, 4, 450000.00, 3, 5.00), -(3, 5, 180000.00, 2, 5.00), --- Order 4 -(4, 1, 1500000.00, 2, 10.00), -(4, 4, 450000.00, 2, 10.00), -(4, 7, 150000.00, 5, 10.00), --- Order 5 -(5, 8, 80000.00, 10, 5.00), -(5, 9, 95000.00, 5, 5.00), -(5, 10, 450000.00, 1, 5.00), --- Order 6 -(6, 11, 350000.00, 5, 5.00), -(6, 13, 45000.00, 20, 5.00), --- Order 7 -(7, 12, 650000.00, 3, 10.00), -(7, 14, 250000.00, 10, 10.00), --- Order 8 -(8, 15, 180000.00, 5, 0.00), -(8, 2, 35000.00, 10, 0.00), --- Order 9 -(9, 6, 25000.00, 30, 0.00), -(9, 13, 45000.00, 5, 0.00), --- Order 10 -(10, 1, 1500000.00, 1, 5.00), -(10, 7, 150000.00, 5, 5.00); - --- ======================================== --- 완료 메시지 --- ======================================== - -SELECT 'Sample data inserted successfully for SQLite!' AS Message; -SELECT 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers -UNION ALL SELECT 'Products', COUNT(*) FROM Products -UNION ALL SELECT 'Employees', COUNT(*) FROM Employees -UNION ALL SELECT 'Orders', COUNT(*) FROM Orders -UNION ALL SELECT 'OrderDetails', COUNT(*) FROM OrderDetails; - diff --git a/resources/sample_data_oracle.sql b/resources/sample_data_oracle.sql deleted file mode 100644 index 4086e75..0000000 --- a/resources/sample_data_oracle.sql +++ /dev/null @@ -1,555 +0,0 @@ --- Customers (100 records) -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST001', '(주)한국전자', '김철수', '김철수@한국전자.co.kr', '02-5316-4710', '서울시 강남구', '서울', '서울', '대한민국', 'VIP', 53700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST002', '(주)서울무역상사', '이영희', '이영희@서울무역상사.co.kr', '02-1695-8934', '서울시 강남구', '부산', '부산', '대한민국', 'Regular', 123500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST003', '(주)부산산업', '박민수', '박민수@부산산업.co.kr', '02-7762-9452', '서울시 강남구', '대구', '대구', '대한민국', 'Premium', 154800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST004', '(주)대구섬유', '최지영', '최지영@대구섬유.co.kr', '02-1656-3419', '서울시 강남구', '인천', '인천', '대한민국', 'Regular', 193700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST005', '(주)인천물류센터', '정현우', '정현우@인천물류센터.co.kr', '02-5754-8948', '서울시 강남구', '광주', '광주', '대한민국', 'Regular', 102900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST006', '(주)광주식품유통', '강수진', '강수진@광주식품유통.co.kr', '02-9874-4597', '서울시 강남구', '대전', '대전', '대한민국', 'Premium', 150500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST007', '(주)제주특산물', '윤서연', '윤서연@제주특산물.co.kr', '02-6922-5234', '서울시 강남구', '울산', '울산', '대한민국', 'VIP', 148900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST008', '(주)울산화학공업', '임동혁', '임동혁@울산화학공업.co.kr', '02-3177-7360', '서울시 강남구', '제주', '제주', '대한민국', 'Premium', 109000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST009', '(주)대전기술연구소', '송미래', '송미래@대전기술연구소.co.kr', '02-5893-6279', '서울시 강남구', '수원', '경기', '대한민국', 'VIP', 120300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST010', '(주)경기통상', '한지훈', '한지훈@경기통상.co.kr', '02-6536-7189', '서울시 강남구', '성남', '강원', '대한민국', 'Premium', 171300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST011', '서울가구', '김영수', '김영수@서울가구.co.kr', '02-2121-9407', '서울시 강남구', '서울', '서울', '대한민국', 'Premium', 74200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST012', '부산수산', '이순희', '이순희@부산수산.co.kr', '02-2912-7151', '서울시 강남구', '부산', '부산', '대한민국', 'Premium', 57900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST013', '대구한방약품', '박건호', '박건호@대구한방약품.co.kr', '02-5929-8312', '서울시 강남구', '대구', '대구', '대한민국', 'Premium', 161700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST014', '인천해운', '최미영', '최미영@인천해운.co.kr', '02-2168-6207', '서울시 강남구', '인천', '인천', '대한민국', 'Regular', 96200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST015', '광주자동차부품', '정태윤', '정태윤@광주자동차부품.co.kr', '02-5155-8632', '서울시 강남구', '광주', '광주', '대한민국', 'VIP', 103100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST016', '제주관광개발', '강민석', '강민석@제주관광개발.co.kr', '02-5909-9230', '서울시 강남구', '대전', '대전', '대한민국', 'Premium', 120400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST017', '울산조선', '윤혜진', '윤혜진@울산조선.co.kr', '02-5809-6472', '서울시 강남구', '울산', '울산', '대한민국', 'Premium', 110100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST018', '대전바이오', '임재현', '임재현@대전바이오.co.kr', '02-6575-2700', '서울시 강남구', '제주', '제주', '대한민국', 'VIP', 47600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST019', '경기반도체', '송현주', '송현주@경기반도체.co.kr', '02-8481-5836', '서울시 강남구', '수원', '경기', '대한민국', 'VIP', 189000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST020', '서울패션', '한수연', '한수연@서울패션.co.kr', '02-1399-8644', '서울시 강남구', '성남', '강원', '대한민국', 'Premium', 181800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST021', '부산철강', '김동현', '김동현@부산철강.co.kr', '02-1637-9028', '서울시 강남구', '서울', '서울', '대한민국', 'Premium', 154800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST022', '대구섬유공업', '이지은', '이지은@대구섬유공업.co.kr', '02-6196-5594', '서울시 강남구', '부산', '부산', '대한민국', 'Regular', 115300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST023', '인천유리', '박상철', '박상철@인천유리.co.kr', '02-7992-5042', '서울시 강남구', '대구', '대구', '대한민국', 'Premium', 70200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST024', '광주전자부품', '최윤정', '최윤정@광주전자부품.co.kr', '02-7672-7850', '서울시 강남구', '인천', '인천', '대한민국', 'Premium', 187500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST025', '제주식품', '정수현', '정수현@제주식품.co.kr', '02-8775-6907', '서울시 강남구', '광주', '광주', '대한민국', 'VIP', 67000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST026', '울산정유', '강태영', '강태영@울산정유.co.kr', '02-7706-6791', '서울시 강남구', '대전', '대전', '대한민국', 'Premium', 63900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST027', '대전전자', '윤미선', '윤미선@대전전자.co.kr', '02-5400-3839', '서울시 강남구', '울산', '울산', '대한민국', 'Premium', 125300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST028', '경기화학', '임경호', '임경호@경기화학.co.kr', '02-4587-5500', '서울시 강남구', '제주', '제주', '대한민국', 'VIP', 82900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST029', '서울건설', '송재민', '송재민@서울건설.co.kr', '02-5696-6022', '서울시 강남구', '수원', '경기', '대한민국', 'VIP', 181500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST030', '부산건설자재', '한영미', '한영미@부산건설자재.co.kr', '02-7331-8295', '서울시 강남구', '성남', '강원', '대한민국', 'VIP', 142500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST031', '대구기계', '김민재', '김민재@대구기계.co.kr', '02-5802-8082', '서울시 강남구', '서울', '서울', '대한민국', 'Regular', 108000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST032', '인천항만', '이상훈', '이상훈@인천항만.co.kr', '02-2617-3714', '서울시 강남구', '부산', '부산', '대한민국', 'Regular', 68700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST033', '광주광산', '박정아', '박정아@광주광산.co.kr', '02-5036-1429', '서울시 강남구', '대구', '대구', '대한민국', 'Premium', 41900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST034', '제주에너지', '최승현', '최승현@제주에너지.co.kr', '02-9730-3282', '서울시 강남구', '인천', '인천', '대한민국', 'VIP', 58500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST035', '울산자동차', '정유진', '정유진@울산자동차.co.kr', '02-5936-3996', '서울시 강남구', '광주', '광주', '대한민국', 'VIP', 108300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST036', '대전소프트웨어', '강도현', '강도현@대전소프트웨어.co.kr', '02-1808-2677', '서울시 강남구', '대전', '대전', '대한민국', 'Regular', 53800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST037', '경기물류', '윤서준', '윤서준@경기물류.co.kr', '02-2867-3411', '서울시 강남구', '울산', '울산', '대한민국', 'Regular', 91400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST038', '서울의료기기', '임하은', '임하은@서울의료기기.co.kr', '02-5441-9871', '서울시 강남구', '제주', '제주', '대한민국', 'VIP', 79100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST039', '부산바이오', '송지우', '송지우@부산바이오.co.kr', '02-2506-8201', '서울시 강남구', '수원', '경기', '대한민국', 'Regular', 191700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST040', '대구IT', '한승우', '한승우@대구it.co.kr', '02-3954-9867', '서울시 강남구', '성남', '강원', '대한민국', 'VIP', 163400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST041', '인천신재생에너지', '김시우', '김시우@인천신재생에너지.co.kr', '02-5293-6538', '서울시 강남구', '서울', '서울', '대한민국', 'Regular', 182400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST042', '광주스마트팩토리', '이예은', '이예은@광주스마트팩토리.co.kr', '02-2893-8274', '서울시 강남구', '부산', '부산', '대한민국', 'Premium', 36700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST043', '제주데이터센터', '박하준', '박하준@제주데이터센터.co.kr', '02-4496-9413', '서울시 강남구', '대구', '대구', '대한민국', 'Regular', 63300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST044', '울산디스플레이', '최서윤', '최서윤@울산디스플레이.co.kr', '02-3428-7072', '서울시 강남구', '인천', '인천', '대한민국', 'VIP', 53900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST045', '대전우주항공', '정민재', '정민재@대전우주항공.co.kr', '02-4522-3126', '서울시 강남구', '광주', '광주', '대한민국', 'Regular', 59800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST046', '경기AI산업', '강유나', '강유나@경기ai산업.co.kr', '02-9176-3292', '서울시 강남구', '대전', '대전', '대한민국', 'VIP', 23100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST047', '서울핀테크', '윤도윤', '윤도윤@서울핀테크.co.kr', '02-3728-3161', '서울시 강남구', '울산', '울산', '대한민국', 'VIP', 40600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST048', '부산로봇산업', '임서준', '임서준@부산로봇산업.co.kr', '02-5643-2442', '서울시 강남구', '제주', '제주', '대한민국', 'Regular', 18500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST049', '대구드론', '송지안', '송지안@대구드론.co.kr', '02-2785-3202', '서울시 강남구', '수원', '경기', '대한민국', 'VIP', 95500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST050', '인천스마트시티', '한예진', '한예진@인천스마트시티.co.kr', '02-9164-7344', '서울시 강남구', '성남', '강원', '대한민국', 'Regular', 137000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST051', 'Tech Solutions Inc', 'John Smith', 'john@tech.com', '+1-555-1066', 'Address', 'San Francisco', 'State', 'USA', 'Premium', 60100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST053', 'Global Trading Co', 'Emily Johnson', 'emily@global.com', '+1-555-4503', 'Address', 'New York', 'State', 'USA', 'Regular', 87300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST055', 'Digital Innovations', 'Michael Brown', 'michael@digital.com', '+1-555-5018', 'Address', 'London', 'State', 'USA', 'Regular', 31200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST057', 'Advanced Manufacturing', 'Sarah Davis', 'sarah@advanced.com', '+1-555-7145', 'Address', 'Berlin', 'State', 'USA', 'VIP', 117200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST059', 'Pacific Logistics', 'David Wilson', 'david@pacific.com', '+1-555-2353', 'Address', 'Sydney', 'State', 'USA', 'VIP', 211800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST061', 'Euro Electronics', 'Sophie Martin', 'sophie@euro.com', '+1-555-1143', 'Address', 'Paris', 'State', 'USA', 'Premium', 106100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST063', 'Asia Pacific Trade', 'James Lee', 'james@asia.com', '+1-555-9428', 'Address', 'Singapore', 'State', 'USA', 'Premium', 69000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST065', 'Northern Industries', 'Emma Anderson', 'emma@northern.com', '+1-555-8457', 'Address', 'Stockholm', 'State', 'USA', 'VIP', 161800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST067', 'Smart Tech Corp', 'Oliver Taylor', 'oliver@smart.com', '+1-555-3993', 'Address', 'Austin', 'State', 'USA', 'Premium', 31300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST069', 'International Supply', 'Isabella Thomas', 'isabella@international.com', '+1-555-3229', 'Address', 'Toronto', 'State', 'USA', 'Regular', 180700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST071', 'Future Systems', 'William Jackson', 'william@future.com', '+1-555-2151', 'Address', 'Tokyo', 'State', 'USA', 'VIP', 113400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST073', 'Green Energy Ltd', 'Olivia White', 'olivia@green.com', '+1-555-6842', 'Address', 'Manchester', 'State', 'USA', 'Premium', 40400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST075', 'Advanced Materials', 'Ethan Harris', 'ethan@advanced.com', '+1-555-3590', 'Address', 'Munich', 'State', 'USA', 'Premium', 158700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST077', 'Ocean Freight Co', 'Ava Martinez', 'ava@ocean.com', '+1-555-1852', 'Address', 'Amsterdam', 'State', 'USA', 'VIP', 237400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST079', 'Digital Commerce', 'Noah Robinson', 'noah@digital.com', '+1-555-5395', 'Address', 'Seattle', 'State', 'USA', 'Premium', 33700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST081', 'Biotech Research', 'Mia Clark', 'mia@biotech.com', '+1-555-4557', 'Address', 'Zurich', 'State', 'USA', 'Regular', 199300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST083', 'Automotive Parts Ltd', 'Lucas Rodriguez', 'lucas@automotive.com', '+1-555-9229', 'Address', 'Milan', 'State', 'USA', 'Regular', 162100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST085', 'Cloud Services Inc', 'Charlotte Lewis', 'charlotte@cloud.com', '+1-555-1743', 'Address', 'Dublin', 'State', 'USA', 'Premium', 58900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST087', 'Pharma Solutions', 'Benjamin Walker', 'benjamin@pharma.com', '+1-555-4048', 'Address', 'Brussels', 'State', 'USA', 'VIP', 54500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST089', 'Robotics International', 'Amelia Hall', 'amelia@robotics.com', '+1-555-1632', 'Address', 'Seoul', 'State', 'USA', 'VIP', 167300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST091', 'Financial Systems', 'Henry Allen', 'henry@financial.com', '+1-555-2367', 'Address', 'Chicago', 'State', 'USA', 'VIP', 218600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST093', 'Renewable Power', 'Harper Young', 'harper@renewable.com', '+1-555-1103', 'Address', 'Copenhagen', 'State', 'USA', 'Regular', 97300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST095', 'Aerospace Tech', 'Alexander King', 'alexander@aerospace.com', '+1-555-7744', 'Address', 'Houston', 'State', 'USA', 'VIP', 238500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST097', 'Smart Agriculture', 'Evelyn Wright', 'evelyn@smart.com', '+1-555-3226', 'Address', 'Rotterdam', 'State', 'USA', 'Regular', 57700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST099', 'Quantum Computing', 'Sebastian Lopez', 'sebastian@quantum.com', '+1-555-9159', 'Address', 'Boston', 'State', 'USA', 'Premium', 47300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST101', 'Marine Solutions', 'Ella Hill', 'ella@marine.com', '+1-555-4786', 'Address', 'Oslo', 'State', 'USA', 'Regular', 64700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST103', 'AI Development', 'Jack Scott', 'jack@ai.com', '+1-555-1143', 'Address', 'San Jose', 'State', 'USA', 'Premium', 179400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST105', 'Logistics Solutions', 'Aria Green', 'aria@logistics.com', '+1-555-8272', 'Address', 'Singapore', 'State', 'USA', 'VIP', 129800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST107', 'Construction Tech', 'Mason Adams', 'mason@construction.com', '+1-555-9216', 'Address', 'Melbourne', 'State', 'USA', 'VIP', 148200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST109', 'Food Processing', 'Luna Baker', 'luna@food.com', '+1-555-6116', 'Address', 'Madrid', 'State', 'USA', 'Regular', 183100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST111', 'Textile Manufacturing', 'Logan Nelson', 'logan@textile.com', '+1-555-4177', 'Address', 'Mumbai', 'State', 'USA', 'Premium', 71700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST113', 'Chemical Industries', 'Layla Carter', 'layla@chemical.com', '+1-555-2167', 'Address', 'São Paulo', 'State', 'USA', 'VIP', 76900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST115', 'Mining Corporation', 'Elijah Mitchell', 'elijah@mining.com', '+1-555-6643', 'Address', 'Johannesburg', 'State', 'USA', 'Regular', 152700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST117', 'Healthcare Systems', 'Chloe Perez', 'chloe@healthcare.com', '+1-555-2876', 'Address', 'Philadelphia', 'State', 'USA', 'Premium', 167100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST119', 'Education Technology', 'Matthew Roberts', 'matthew@education.com', '+1-555-8047', 'Address', 'Edinburgh', 'State', 'USA', 'Regular', 155200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST121', 'Entertainment Media', 'Avery Turner', 'avery@entertainment.com', '+1-555-3098', 'Address', 'Los Angeles', 'State', 'USA', 'VIP', 95900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST123', 'Security Solutions', 'Daniel Phillips', 'daniel@security.com', '+1-555-4491', 'Address', 'Tel Aviv', 'State', 'USA', 'Regular', 76300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST125', 'Environmental Tech', 'Sofia Campbell', 'sofia@environmental.com', '+1-555-1632', 'Address', 'Helsinki', 'State', 'USA', 'Regular', 81700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST127', 'Transportation Systems', 'Joseph Parker', 'joseph@transportation.com', '+1-555-6859', 'Address', 'Vienna', 'State', 'USA', 'VIP', 166100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST129', 'Telecommunications', 'Victoria Evans', 'victoria@telecommunications.com', '+1-555-1110', 'Address', 'Hong Kong', 'State', 'USA', 'Premium', 48100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST131', 'Water Treatment', 'David Edwards', 'david@water.com', '+1-555-5666', 'Address', 'Dubai', 'State', 'USA', 'Regular', 22100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST133', 'Fashion Design', 'Grace Collins', 'grace@fashion.com', '+1-555-2103', 'Address', 'Paris', 'State', 'USA', 'VIP', 117100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST135', 'Gaming Studios', 'Samuel Stewart', 'samuel@gaming.com', '+1-555-6111', 'Address', 'San Francisco', 'State', 'USA', 'Regular', 244100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST137', 'Space Technology', 'Zoe Sanchez', 'zoe@space.com', '+1-555-7494', 'Address', 'Cape Canaveral', 'State', 'USA', 'VIP', 83300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST139', 'Furniture Design', 'Ryan Morris', 'ryan@furniture.com', '+1-555-3597', 'Address', 'Gothenburg', 'State', 'USA', 'Regular', 192500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST141', 'Printing Services', 'Penelope Rogers', 'penelope@printing.com', '+1-555-7950', 'Address', 'Hamburg', 'State', 'USA', 'Regular', 69900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST143', 'Packaging Solutions', 'Isaac Reed', 'isaac@packaging.com', '+1-555-4830', 'Address', 'Atlanta', 'State', 'USA', 'Premium', 212400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST145', 'Laboratory Equipment', 'Stella Cook', 'stella@laboratory.com', '+1-555-8700', 'Address', 'Basel', 'State', 'USA', 'Premium', 157300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST147', 'Sports Equipment', 'Christian Morgan', 'christian@sports.com', '+1-555-1038', 'Address', 'Denver', 'State', 'USA', 'Premium', 106700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST149', 'Defense Systems', 'Nora Bell', 'nora@defense.com', '+1-555-5976', 'Address', 'Arlington', 'State', 'USA', 'VIP', 148100000.00, 1); --- Products (100 records) -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-100', '노트북', '전자제품', 1885.80, 231, 170, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-101', '마우스', '전자제품', 1723.66, 291, 117, 41, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-102', '키보드', '전자제품', 1832.15, 111, 175, 37, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-103', '모니터', '전자제품', 1331.13, 330, 173, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-104', '외장 SSD', '저장장치', 1464.31, 4, 156, 35, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-105', 'USB 메모리', '저장장치', 1509.59, 429, 197, 29, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-106', '이어폰', '오디오', 795.13, 467, 195, 22, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-107', '스피커', '오디오', 385.69, 83, 157, 43, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-108', '웹캠', '전자제품', 762.79, 47, 123, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-109', '태블릿', '전자제품', 681.74, 366, 22, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-110', '프린터', '사무기기', 384.62, 184, 1, 17, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-111', '복합기', '사무기기', 1134.50, 156, 55, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-112', '스탠드', '사무용품', 1146.98, 138, 98, 42, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-113', '의자', '가구', 1765.11, 475, 130, 12, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-114', '캐비닛', '가구', 487.49, 491, 144, 41, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-115', '책상', '가구', 1204.69, 321, 67, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-116', '램프', '사무용품', 462.98, 221, 23, 0, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-117', '충전기', '전자제품', 1225.90, 345, 60, 10, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-118', '케이블', '전자제품', 815.92, 366, 186, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-119', '허브', '전자제품', 1483.06, 161, 139, 37, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-120', '헤드셋', '오디오', 552.96, 484, 176, 3, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-121', '마이크', '오디오', 890.28, 109, 54, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-122', '스캐너', '사무기기', 1380.48, 158, 32, 16, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-123', '라벨기', '사무기기', 1085.34, 169, 155, 25, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-124', '계산기', '사무용품', 1247.94, 168, 10, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-125', '화이트보드', '사무용품', 1049.47, 39, 46, 12, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-126', '복사기', '사무기기', 1125.62, 452, 16, 43, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-127', '파쇄기', '사무기기', 1156.99, 488, 151, 39, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-128', '바인더', '사무용품', 1010.69, 103, 155, 45, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-129', '필기구', '사무용품', 224.66, 132, 3, 9, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-130', '노트', '사무용품', 276.64, 474, 27, 22, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-131', '파일', '사무용품', 397.28, 98, 105, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-132', '클립', '사무용품', 1415.64, 69, 127, 0, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-133', '테이프', '사무용품', 1505.14, 154, 1, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-134', '가위', '사무용품', 1397.42, 208, 3, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-135', '스테이플러', '사무용품', 1168.61, 372, 148, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-136', '펀치', '사무용품', 690.43, 4, 73, 16, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-137', '자', '사무용품', 1666.25, 473, 164, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-138', '형광펜', '사무용품', 920.60, 139, 145, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-139', '지우개', '사무용품', 1963.77, 132, 92, 6, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-140', '수정테이프', '사무용품', 660.63, 460, 12, 20, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-141', '포스트잇', '사무용품', 1627.23, 93, 132, 24, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-142', '달력', '사무용품', 489.17, 143, 184, 37, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-143', '플래너', '사무용품', 1302.03, 433, 57, 31, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-144', '시계', '사무용품', 1649.99, 147, 117, 21, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-145', '쓰레기통', '사무용품', 1931.04, 42, 138, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-146', '우산꽂이', '사무용품', 488.96, 40, 9, 21, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-147', '신발장', '가구', 494.65, 182, 148, 48, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-148', '사물함', '가구', 899.73, 274, 191, 16, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-149', '칸막이', '가구', 1921.81, 317, 190, 14, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-200', 'Laptop Computer', 'Electronics', 214.01, 477, 62, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-201', 'Wireless Mouse', 'Electronics', 857.38, 394, 146, 3, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-202', 'Mechanical Keyboard', 'Electronics', 1405.09, 488, 151, 36, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-203', 'Monitor 27inch', 'Electronics', 1098.86, 113, 67, 19, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-204', 'External SSD', 'Storage', 1158.88, 125, 0, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-205', 'USB Flash Drive', 'Storage', 313.13, 400, 28, 5, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-206', 'Wireless Earbuds', 'Audio', 980.68, 267, 107, 24, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-207', 'Bluetooth Speaker', 'Audio', 809.97, 174, 2, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-208', 'HD Webcam', 'Electronics', 1877.94, 500, 8, 6, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-209', 'Tablet Device', 'Electronics', 1116.86, 408, 16, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-210', 'Laser Printer', 'Office Equipment', 175.43, 75, 47, 23, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-211', 'Multifunction Printer', 'Office Equipment', 106.59, 37, 43, 12, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-212', 'Desk Lamp', 'Office Supplies', 1886.54, 10, 0, 14, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-213', 'Office Chair', 'Furniture', 248.78, 32, 197, 21, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-214', 'File Cabinet', 'Furniture', 211.99, 262, 87, 21, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-215', 'Standing Desk', 'Furniture', 442.89, 162, 27, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-216', 'LED Lamp', 'Office Supplies', 1026.44, 35, 170, 47, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-217', 'Power Adapter', 'Electronics', 1796.59, 467, 149, 44, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-218', 'USB Cable', 'Electronics', 691.15, 86, 130, 15, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-219', 'USB Hub', 'Electronics', 1130.55, 435, 11, 18, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-220', 'Gaming Headset', 'Audio', 1854.29, 351, 112, 14, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-221', 'Studio Microphone', 'Audio', 819.20, 206, 9, 5, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-222', 'Document Scanner', 'Office Equipment', 787.83, 162, 6, 19, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-223', 'Label Printer', 'Office Equipment', 769.70, 98, 98, 13, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-224', 'Calculator', 'Office Supplies', 600.19, 424, 157, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-225', 'Whiteboard', 'Office Supplies', 835.75, 184, 192, 0, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-226', 'Copier', 'Office Equipment', 1855.97, 450, 100, 22, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-227', 'Paper Shredder', 'Office Equipment', 989.21, 493, 162, 23, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-228', 'Ring Binder', 'Office Supplies', 1657.46, 456, 120, 16, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-229', 'Pen Set', 'Office Supplies', 1993.41, 472, 145, 43, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-230', 'Notebook', 'Office Supplies', 592.21, 171, 63, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-231', 'File Folder', 'Office Supplies', 1776.42, 418, 40, 13, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-232', 'Paper Clips', 'Office Supplies', 1082.70, 311, 104, 44, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-233', 'Adhesive Tape', 'Office Supplies', 263.80, 141, 71, 37, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-234', 'Scissors', 'Office Supplies', 1516.43, 384, 16, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-235', 'Stapler', 'Office Supplies', 54.18, 364, 42, 8, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-236', 'Hole Punch', 'Office Supplies', 1731.30, 261, 198, 34, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-237', 'Ruler Set', 'Office Supplies', 82.50, 468, 200, 22, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-238', 'Highlighter', 'Office Supplies', 605.59, 16, 117, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-239', 'Eraser', 'Office Supplies', 323.85, 201, 180, 8, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-240', 'Correction Tape', 'Office Supplies', 1780.23, 244, 21, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-241', 'Sticky Notes', 'Office Supplies', 1990.92, 323, 98, 41, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-242', 'Wall Calendar', 'Office Supplies', 540.42, 19, 116, 42, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-243', 'Daily Planner', 'Office Supplies', 1715.67, 16, 118, 43, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-244', 'Wall Clock', 'Office Supplies', 1290.24, 337, 103, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-245', 'Waste Bin', 'Office Supplies', 1602.94, 5, 27, 45, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-246', 'Umbrella Stand', 'Office Supplies', 152.76, 333, 21, 19, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-247', 'Shoe Rack', 'Furniture', 1333.53, 334, 187, 27, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-248', 'Storage Locker', 'Furniture', 813.48, 408, 6, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-249', 'Privacy Screen', 'Furniture', 1755.71, 54, 174, 6, 0, NULL); --- Employees (50 records) -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-001', 'Fiona', 'Han', 'Assistant', TO_DATE('1974-12-03', 'YYYY-MM-DD'), TO_DATE('2019-05-21', 'YYYY-MM-DD'), 'fiona.han@example.com', '010-4259-5016', 'Marketing', 8310.26, NULL, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-002', 'Cathy', 'Yoon', 'Analyst', TO_DATE('1971-01-07', 'YYYY-MM-DD'), TO_DATE('2020-05-07', 'YYYY-MM-DD'), 'cathy.yoon@example.com', '010-2056-9111', 'Finance', 8147.35, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-003', 'Fiona', 'Park', 'Analyst', TO_DATE('1984-07-20', 'YYYY-MM-DD'), TO_DATE('2020-06-26', 'YYYY-MM-DD'), 'fiona.park@example.com', '010-6009-1341', 'IT', 7361.22, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-004', 'Alice', 'Song', 'Director', TO_DATE('1985-09-09', 'YYYY-MM-DD'), TO_DATE('2017-11-01', 'YYYY-MM-DD'), 'alice.song@example.com', '010-2421-2950', 'HR', 4167.49, 3, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-005', 'Hanna', 'Kim', 'Analyst', TO_DATE('1997-07-09', 'YYYY-MM-DD'), TO_DATE('2025-02-27', 'YYYY-MM-DD'), 'hanna.kim@example.com', '010-3554-8589', 'Finance', 4389.85, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-006', 'Hanna', 'Kim', 'Assistant', TO_DATE('1977-05-14', 'YYYY-MM-DD'), TO_DATE('2021-07-09', 'YYYY-MM-DD'), 'hanna.kim@example.com', '010-3395-4400', 'Marketing', 4452.07, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-007', 'George', 'Kang', 'Director', TO_DATE('2008-10-04', 'YYYY-MM-DD'), TO_DATE('2025-10-12', 'YYYY-MM-DD'), 'george.kang@example.com', '010-7465-3760', 'Marketing', 3460.48, 3, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-008', 'Brian', 'Kang', 'Director', TO_DATE('2019-11-28', 'YYYY-MM-DD'), TO_DATE('2022-05-08', 'YYYY-MM-DD'), 'brian.kang@example.com', '010-8379-8636', 'Finance', 3423.13, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-009', 'Cathy', 'Park', 'Engineer', TO_DATE('2008-07-24', 'YYYY-MM-DD'), TO_DATE('2024-08-28', 'YYYY-MM-DD'), 'cathy.park@example.com', '010-7855-1994', 'HR', 8736.51, 7, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-010', 'David', 'Choi', 'Analyst', TO_DATE('2023-06-15', 'YYYY-MM-DD'), TO_DATE('2018-04-23', 'YYYY-MM-DD'), 'david.choi@example.com', '010-4044-7035', 'Marketing', 3594.76, 8, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-011', 'Cathy', 'Han', 'Manager', TO_DATE('1985-01-10', 'YYYY-MM-DD'), TO_DATE('2015-12-17', 'YYYY-MM-DD'), 'cathy.han@example.com', '010-2061-8091', 'Sales', 7418.76, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-012', 'Cathy', 'Kim', 'Assistant', TO_DATE('1986-04-06', 'YYYY-MM-DD'), TO_DATE('2019-05-27', 'YYYY-MM-DD'), 'cathy.kim@example.com', '010-5534-1801', 'Sales', 5779.65, 7, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-013', 'Alice', 'Lim', 'Engineer', TO_DATE('1982-11-05', 'YYYY-MM-DD'), TO_DATE('2016-01-09', 'YYYY-MM-DD'), 'alice.lim@example.com', '010-2641-6324', 'Finance', 8980.98, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-014', 'Fiona', 'Song', 'Director', TO_DATE('2013-05-01', 'YYYY-MM-DD'), TO_DATE('2021-07-20', 'YYYY-MM-DD'), 'fiona.song@example.com', '010-8101-1693', 'HR', 8280.96, 11, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-015', 'Evan', 'Kang', 'Assistant', TO_DATE('2021-07-13', 'YYYY-MM-DD'), TO_DATE('2017-11-10', 'YYYY-MM-DD'), 'evan.kang@example.com', '010-5933-6990', 'Sales', 7853.72, 11, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-016', 'Brian', 'Song', 'Assistant', TO_DATE('1982-03-09', 'YYYY-MM-DD'), TO_DATE('2021-02-21', 'YYYY-MM-DD'), 'brian.song@example.com', '010-8990-1357', 'HR', 4346.13, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-017', 'Alice', 'Yoon', 'Engineer', TO_DATE('1980-06-05', 'YYYY-MM-DD'), TO_DATE('2022-10-21', 'YYYY-MM-DD'), 'alice.yoon@example.com', '010-5558-4595', 'Sales', 6220.73, 14, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-018', 'Fiona', 'Kim', 'Assistant', TO_DATE('2017-03-17', 'YYYY-MM-DD'), TO_DATE('2018-06-13', 'YYYY-MM-DD'), 'fiona.kim@example.com', '010-8054-9683', 'Finance', 5856.50, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-019', 'Alice', 'Kang', 'Manager', TO_DATE('2014-10-03', 'YYYY-MM-DD'), TO_DATE('2023-08-01', 'YYYY-MM-DD'), 'alice.kang@example.com', '010-9793-8558', 'HR', 4836.09, 9, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-020', 'George', 'Jung', 'Analyst', TO_DATE('1989-06-16', 'YYYY-MM-DD'), TO_DATE('2022-07-15', 'YYYY-MM-DD'), 'george.jung@example.com', '010-7633-8704', 'IT', 3898.46, 5, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-021', 'Alice', 'Yoon', 'Manager', TO_DATE('2012-08-23', 'YYYY-MM-DD'), TO_DATE('2023-11-26', 'YYYY-MM-DD'), 'alice.yoon@example.com', '010-8085-7730', 'HR', 7043.88, 18, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-022', 'Cathy', 'Lee', 'Engineer', TO_DATE('1998-01-22', 'YYYY-MM-DD'), TO_DATE('2024-11-01', 'YYYY-MM-DD'), 'cathy.lee@example.com', '010-1823-9261', 'HR', 8878.70, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-023', 'George', 'Yoon', 'Manager', TO_DATE('2010-07-21', 'YYYY-MM-DD'), TO_DATE('2021-09-15', 'YYYY-MM-DD'), 'george.yoon@example.com', '010-8443-4252', 'Marketing', 6587.18, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-024', 'Julia', 'Choi', 'Engineer', TO_DATE('1989-04-29', 'YYYY-MM-DD'), TO_DATE('2020-11-17', 'YYYY-MM-DD'), 'julia.choi@example.com', '010-5806-7126', 'Finance', 8216.39, 14, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-025', 'George', 'Han', 'Engineer', TO_DATE('2021-12-27', 'YYYY-MM-DD'), TO_DATE('2025-09-03', 'YYYY-MM-DD'), 'george.han@example.com', '010-1778-3618', 'Marketing', 5829.09, 7, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-026', 'George', 'Lee', 'Assistant', TO_DATE('2011-01-23', 'YYYY-MM-DD'), TO_DATE('2019-12-05', 'YYYY-MM-DD'), 'george.lee@example.com', '010-4864-9314', 'Finance', 3400.15, 19, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-027', 'Cathy', 'Kim', 'Manager', TO_DATE('1990-03-26', 'YYYY-MM-DD'), TO_DATE('2018-04-22', 'YYYY-MM-DD'), 'cathy.kim@example.com', '010-8417-8996', 'HR', 7230.78, 25, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-028', 'Hanna', 'Lee', 'Assistant', TO_DATE('1988-06-10', 'YYYY-MM-DD'), TO_DATE('2017-04-22', 'YYYY-MM-DD'), 'hanna.lee@example.com', '010-6396-2223', 'IT', 5603.85, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-029', 'David', 'Park', 'Analyst', TO_DATE('1995-08-03', 'YYYY-MM-DD'), TO_DATE('2021-02-13', 'YYYY-MM-DD'), 'david.park@example.com', '010-1552-2499', 'Finance', 8368.75, 2, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-030', 'David', 'Song', 'Director', TO_DATE('1970-10-22', 'YYYY-MM-DD'), TO_DATE('2019-03-10', 'YYYY-MM-DD'), 'david.song@example.com', '010-3051-9495', 'HR', 3532.43, 13, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-031', 'Ian', 'Lee', 'Director', TO_DATE('2011-09-06', 'YYYY-MM-DD'), TO_DATE('2021-01-02', 'YYYY-MM-DD'), 'ian.lee@example.com', '010-5204-7084', 'IT', 7237.59, 20, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-032', 'Hanna', 'Han', 'Engineer', TO_DATE('1983-10-22', 'YYYY-MM-DD'), TO_DATE('2017-05-15', 'YYYY-MM-DD'), 'hanna.han@example.com', '010-1893-9710', 'Marketing', 8135.45, 17, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-033', 'Ian', 'Lee', 'Analyst', TO_DATE('1984-08-06', 'YYYY-MM-DD'), TO_DATE('2023-04-16', 'YYYY-MM-DD'), 'ian.lee@example.com', '010-3471-3357', 'HR', 7854.05, 28, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-034', 'Ian', 'Song', 'Engineer', TO_DATE('2012-10-09', 'YYYY-MM-DD'), TO_DATE('2018-09-26', 'YYYY-MM-DD'), 'ian.song@example.com', '010-8683-7106', 'Finance', 6809.61, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-035', 'George', 'Park', 'Director', TO_DATE('1979-11-23', 'YYYY-MM-DD'), TO_DATE('2019-04-13', 'YYYY-MM-DD'), 'george.park@example.com', '010-7932-7469', 'HR', 8956.43, 8, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-036', 'George', 'Kang', 'Analyst', TO_DATE('1972-08-18', 'YYYY-MM-DD'), TO_DATE('2019-11-01', 'YYYY-MM-DD'), 'george.kang@example.com', '010-6173-8750', 'Finance', 4866.05, 26, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-037', 'Brian', 'Kim', 'Assistant', TO_DATE('1993-10-21', 'YYYY-MM-DD'), TO_DATE('2015-11-07', 'YYYY-MM-DD'), 'brian.kim@example.com', '010-8454-9517', 'HR', 6505.02, 32, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-038', 'Cathy', 'Kim', 'Assistant', TO_DATE('2011-09-03', 'YYYY-MM-DD'), TO_DATE('2023-01-04', 'YYYY-MM-DD'), 'cathy.kim@example.com', '010-8433-4592', 'IT', 3704.05, 34, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-039', 'Hanna', 'Han', 'Assistant', TO_DATE('1988-11-30', 'YYYY-MM-DD'), TO_DATE('2018-10-24', 'YYYY-MM-DD'), 'hanna.han@example.com', '010-3149-2070', 'HR', 4760.71, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-040', 'Hanna', 'Lee', 'Director', TO_DATE('2022-03-27', 'YYYY-MM-DD'), TO_DATE('2023-11-09', 'YYYY-MM-DD'), 'hanna.lee@example.com', '010-7484-7862', 'Sales', 4161.92, 31, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-041', 'Cathy', 'Han', 'Assistant', TO_DATE('2013-05-26', 'YYYY-MM-DD'), TO_DATE('2017-06-14', 'YYYY-MM-DD'), 'cathy.han@example.com', '010-8284-2950', 'Sales', 3242.95, 35, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-042', 'George', 'Yoon', 'Assistant', TO_DATE('1984-08-27', 'YYYY-MM-DD'), TO_DATE('2020-06-06', 'YYYY-MM-DD'), 'george.yoon@example.com', '010-4194-8669', 'Finance', 6057.07, 18, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-043', 'Cathy', 'Park', 'Engineer', TO_DATE('1981-03-08', 'YYYY-MM-DD'), TO_DATE('2020-02-10', 'YYYY-MM-DD'), 'cathy.park@example.com', '010-8249-7710', 'Marketing', 6990.77, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-044', 'Evan', 'Lim', 'Manager', TO_DATE('2008-08-22', 'YYYY-MM-DD'), TO_DATE('2016-08-25', 'YYYY-MM-DD'), 'evan.lim@example.com', '010-6865-4182', 'Finance', 6371.06, 41, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-045', 'Fiona', 'Lee', 'Analyst', TO_DATE('1975-05-12', 'YYYY-MM-DD'), TO_DATE('2024-08-24', 'YYYY-MM-DD'), 'fiona.lee@example.com', '010-5865-3346', 'IT', 8456.36, 33, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-046', 'George', 'Lim', 'Manager', TO_DATE('2009-05-15', 'YYYY-MM-DD'), TO_DATE('2024-04-20', 'YYYY-MM-DD'), 'george.lim@example.com', '010-9234-6947', 'Finance', 7759.34, 26, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-047', 'Fiona', 'Yoon', 'Director', TO_DATE('2017-05-03', 'YYYY-MM-DD'), TO_DATE('2024-02-13', 'YYYY-MM-DD'), 'fiona.yoon@example.com', '010-4551-1405', 'Finance', 6798.80, 22, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-048', 'Hanna', 'Kang', 'Assistant', TO_DATE('1994-10-31', 'YYYY-MM-DD'), TO_DATE('2016-06-22', 'YYYY-MM-DD'), 'hanna.kang@example.com', '010-6177-7395', 'Sales', 8799.98, 33, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-049', 'Ian', 'Lim', 'Assistant', TO_DATE('1977-01-10', 'YYYY-MM-DD'), TO_DATE('2023-08-09', 'YYYY-MM-DD'), 'ian.lim@example.com', '010-1319-1453', 'IT', 7268.65, 8, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-050', 'Hanna', 'Lim', 'Engineer', TO_DATE('1994-06-08', 'YYYY-MM-DD'), TO_DATE('2020-08-28', 'YYYY-MM-DD'), 'hanna.lim@example.com', '010-5497-3448', 'IT', 6616.61, 13, 1); --- Orders (100 records) -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400001', 47, TO_TIMESTAMP('2024-01-16 07:44:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-21 07:44:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-23 07:44:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 1301.24, 130.12, 1431.36, 'Wire', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400002', 31, TO_TIMESTAMP('2024-01-18 07:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-28 07:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 07:33:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 65.90, 6.59, 72.49, 'Cash', 'Unpaid', 34, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400003', 33, TO_TIMESTAMP('2024-02-28 04:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-05 04:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-29 04:25:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 4451.12, 445.11, 4896.23, 'Wire', 'Paid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400004', 41, TO_TIMESTAMP('2024-01-13 00:47:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-19 00:47:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 3604.77, 360.48, 3965.25, 'Cash', 'Unpaid', 34, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400005', 84, TO_TIMESTAMP('2024-02-24 03:02:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-25 03:02:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-27 03:02:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3742.71, 374.27, 4116.98, 'Card', 'Paid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400006', 84, TO_TIMESTAMP('2024-01-06 10:14:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-08 10:14:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 10:14:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3181.09, 318.11, 3499.20, 'Wire', 'Paid', 33, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400007', 98, TO_TIMESTAMP('2024-01-03 23:38:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-04 23:38:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 2163.76, 216.38, 2380.14, 'Wire', 'Unpaid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400008', 21, TO_TIMESTAMP('2024-02-07 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-09 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-12 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2213.82, 221.38, 2435.20, 'Cash', 'Paid', 44, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400009', 89, TO_TIMESTAMP('2024-02-03 15:20:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-10 15:20:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-09 15:20:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2044.93, 204.49, 2249.42, 'Wire', 'Paid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400010', 45, TO_TIMESTAMP('2024-02-21 04:12:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-22 04:12:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 1917.93, 191.79, 2109.72, 'Card', 'Unpaid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400011', 37, TO_TIMESTAMP('2024-01-13 16:36:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-19 16:36:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 1167.73, 116.77, 1284.50, 'Cash', 'Paid', 4, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400012', 40, TO_TIMESTAMP('2024-01-03 03:17:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-06 03:17:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 03:17:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1976.71, 197.67, 2174.38, 'Cash', 'Paid', 15, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400013', 21, TO_TIMESTAMP('2024-02-10 16:20:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-19 16:20:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 2852.74, 285.27, 3138.01, 'Wire', 'Paid', 28, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400014', 56, TO_TIMESTAMP('2024-01-13 13:45:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-21 13:45:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-14 13:45:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 420.79, 42.08, 462.87, 'Wire', 'Unpaid', 46, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400015', 17, TO_TIMESTAMP('2024-01-17 06:53:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-19 06:53:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-21 06:53:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1149.65, 114.97, 1264.62, 'Card', 'Paid', 21, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400016', 84, TO_TIMESTAMP('2024-01-27 22:06:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-01 22:06:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 3687.03, 368.70, 4055.73, 'Card', 'Paid', 3, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400017', 35, TO_TIMESTAMP('2024-03-01 03:31:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-08 03:31:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-08 03:31:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 4162.51, 416.25, 4578.76, 'Cash', 'Paid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400018', 52, TO_TIMESTAMP('2024-02-22 05:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-26 05:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-27 05:04:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 525.92, 52.59, 578.51, 'Cash', 'Paid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400019', 18, TO_TIMESTAMP('2024-02-17 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-20 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-18 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2315.09, 231.51, 2546.60, 'Cash', 'Unpaid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400020', 56, TO_TIMESTAMP('2024-01-20 10:27:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 10:27:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-26 10:27:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1681.17, 168.12, 1849.29, 'Cash', 'Unpaid', 41, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400021', 57, TO_TIMESTAMP('2024-01-24 23:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-28 23:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-31 23:25:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 2717.74, 271.77, 2989.51, 'Card', 'Unpaid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400022', 7, TO_TIMESTAMP('2024-01-28 15:18:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-30 15:18:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-30 15:18:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 957.60, 95.76, 1053.36, 'Wire', 'Paid', 19, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400023', 29, TO_TIMESTAMP('2024-01-25 07:41:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-02 07:41:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-31 07:41:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 3005.50, 300.55, 3306.05, 'Cash', 'Unpaid', 5, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400024', 40, TO_TIMESTAMP('2024-01-15 12:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-21 12:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-20 12:34:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 434.04, 43.40, 477.44, 'Wire', 'Unpaid', 3, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400025', 94, TO_TIMESTAMP('2024-02-19 17:08:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-25 17:08:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 3744.89, 374.49, 4119.38, 'Card', 'Unpaid', 32, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400026', 75, TO_TIMESTAMP('2024-01-20 18:32:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 18:32:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 1469.16, 146.92, 1616.08, 'Card', 'Unpaid', 44, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400027', 33, TO_TIMESTAMP('2024-01-03 04:38:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-08 04:38:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-05 04:38:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2857.32, 285.73, 3143.05, 'Wire', 'Paid', 6, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400028', 79, TO_TIMESTAMP('2024-01-06 22:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-08 22:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 22:00:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3912.98, 391.30, 4304.28, 'Cash', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400029', 63, TO_TIMESTAMP('2024-02-06 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-10 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-09 14:33:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 1980.21, 198.02, 2178.23, 'Wire', 'Unpaid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400030', 66, TO_TIMESTAMP('2024-02-01 05:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-05 05:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-05 05:39:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 4376.32, 437.63, 4813.95, 'Cash', 'Paid', 16, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400031', 85, TO_TIMESTAMP('2024-01-10 07:40:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-15 07:40:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-12 07:40:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2972.08, 297.21, 3269.29, 'Cash', 'Paid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400032', 26, TO_TIMESTAMP('2024-02-06 05:30:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-07 05:30:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-10 05:30:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 2321.76, 232.18, 2553.94, 'Card', 'Paid', 38, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400033', 59, TO_TIMESTAMP('2024-02-21 22:56:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-28 22:56:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-28 22:56:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 461.61, 46.16, 507.77, 'Card', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400034', 77, TO_TIMESTAMP('2024-02-06 04:07:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-08 04:07:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 4141.47, 414.15, 4555.62, 'Card', 'Unpaid', 3, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400035', 56, TO_TIMESTAMP('2024-02-05 20:52:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-06 20:52:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-07 20:52:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3894.68, 389.47, 4284.15, 'Wire', 'Paid', 25, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400036', 94, TO_TIMESTAMP('2024-02-06 22:41:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-12 22:41:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-10 22:41:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3643.02, 364.30, 4007.32, 'Cash', 'Paid', 46, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400037', 21, TO_TIMESTAMP('2024-02-22 02:52:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-24 02:52:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-29 02:52:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3815.16, 381.52, 4196.68, 'Card', 'Unpaid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400038', 10, TO_TIMESTAMP('2024-01-05 03:22:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 03:22:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 1429.50, 142.95, 1572.45, 'Cash', 'Unpaid', 18, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400039', 83, TO_TIMESTAMP('2024-01-12 16:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-17 16:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-16 16:04:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1025.52, 102.55, 1128.07, 'Cash', 'Paid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400040', 62, TO_TIMESTAMP('2024-01-12 07:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-19 07:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-16 07:39:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 2099.26, 209.93, 2309.19, 'Wire', 'Paid', 41, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400041', 88, TO_TIMESTAMP('2024-01-08 07:07:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-17 07:07:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-11 07:07:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2138.21, 213.82, 2352.03, 'Wire', 'Unpaid', 16, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400042', 78, TO_TIMESTAMP('2024-01-07 04:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-15 04:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 04:34:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 3577.04, 357.70, 3934.74, 'Wire', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400043', 41, TO_TIMESTAMP('2024-02-06 20:15:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-08 20:15:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-13 20:15:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 4366.86, 436.69, 4803.55, 'Card', 'Unpaid', 18, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400044', 79, TO_TIMESTAMP('2024-02-22 17:08:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-27 17:08:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-28 17:08:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 4866.12, 486.61, 5352.73, 'Card', 'Unpaid', 17, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400045', 86, TO_TIMESTAMP('2024-02-10 04:16:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-19 04:16:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-15 04:16:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 853.90, 85.39, 939.29, 'Card', 'Unpaid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400046', 16, TO_TIMESTAMP('2024-01-21 16:09:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-26 16:09:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 16:09:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2417.86, 241.79, 2659.65, 'Wire', 'Paid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400047', 26, TO_TIMESTAMP('2024-01-31 12:53:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-01 12:53:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-02 12:53:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 151.03, 15.10, 166.13, 'Cash', 'Paid', 28, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400048', 54, TO_TIMESTAMP('2024-02-16 09:57:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-20 09:57:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-19 09:57:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3310.93, 331.09, 3642.02, 'Wire', 'Unpaid', 50, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400049', 91, TO_TIMESTAMP('2024-02-16 11:40:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-21 11:40:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-22 11:40:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 327.79, 32.78, 360.57, 'Card', 'Paid', 17, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400050', 54, TO_TIMESTAMP('2024-01-21 20:55:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-28 20:55:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-26 20:55:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 408.17, 40.82, 448.99, 'Wire', 'Unpaid', 7, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400051', 35, TO_TIMESTAMP('2024-01-27 18:01:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-30 18:01:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 2180.09, 218.01, 2398.10, 'Cash', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400052', 81, TO_TIMESTAMP('2024-01-28 06:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-29 06:49:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 4671.58, 467.16, 5138.74, 'Card', 'Unpaid', 24, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400053', 50, TO_TIMESTAMP('2024-01-31 09:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-04 09:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-07 09:39:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2926.77, 292.68, 3219.45, 'Wire', 'Paid', 29, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400054', 22, TO_TIMESTAMP('2024-02-24 06:07:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-27 06:07:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-27 06:07:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1438.67, 143.87, 1582.54, 'Wire', 'Unpaid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400055', 12, TO_TIMESTAMP('2024-01-18 19:46:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-21 19:46:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 2921.70, 292.17, 3213.87, 'Cash', 'Unpaid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400056', 35, TO_TIMESTAMP('2024-02-29 15:09:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-10 15:09:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-02 15:09:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2371.44, 237.14, 2608.58, 'Wire', 'Unpaid', 9, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400057', 77, TO_TIMESTAMP('2024-01-24 23:17:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-25 23:17:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 885.52, 88.55, 974.07, 'Card', 'Unpaid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400058', 25, TO_TIMESTAMP('2024-02-02 21:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-07 21:34:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 3203.59, 320.36, 3523.95, 'Wire', 'Paid', 40, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400059', 36, TO_TIMESTAMP('2024-02-12 21:05:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-18 21:05:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-17 21:05:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3924.06, 392.41, 4316.47, 'Card', 'Unpaid', 5, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400060', 81, TO_TIMESTAMP('2024-02-17 23:51:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-23 23:51:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 4613.85, 461.39, 5075.24, 'Cash', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400061', 51, TO_TIMESTAMP('2024-01-03 23:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-09 23:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-08 23:34:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 1500.98, 150.10, 1651.08, 'Wire', 'Unpaid', 38, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400062', 60, TO_TIMESTAMP('2024-01-18 00:22:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 00:22:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-24 00:22:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 4014.67, 401.47, 4416.14, 'Wire', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400063', 84, TO_TIMESTAMP('2024-02-29 09:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-06 09:25:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-05 09:25:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3948.63, 394.86, 4343.49, 'Cash', 'Paid', 43, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400064', 89, TO_TIMESTAMP('2024-01-13 08:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-17 08:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-16 08:39:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 135.29, 13.53, 148.82, 'Wire', 'Paid', 11, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400065', 21, TO_TIMESTAMP('2024-01-13 15:31:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-23 15:31:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-18 15:31:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 974.74, 97.47, 1072.21, 'Card', 'Paid', 24, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400066', 62, TO_TIMESTAMP('2024-01-21 17:43:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-26 17:43:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-25 17:43:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 80.76, 8.08, 88.84, 'Cash', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400067', 22, TO_TIMESTAMP('2024-02-03 07:42:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-09 07:42:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-04 07:42:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 1625.42, 162.54, 1787.96, 'Card', 'Paid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400068', 90, TO_TIMESTAMP('2024-01-14 06:51:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-22 06:51:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-17 06:51:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 3038.76, 303.88, 3342.64, 'Wire', 'Unpaid', 47, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400069', 85, TO_TIMESTAMP('2024-02-14 01:48:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-20 01:48:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-16 01:48:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 4685.30, 468.53, 5153.83, 'Card', 'Paid', 42, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400070', 66, TO_TIMESTAMP('2024-02-25 17:21:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-06 17:21:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-26 17:21:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 146.41, 14.64, 161.05, 'Card', 'Unpaid', 5, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400071', 70, TO_TIMESTAMP('2024-02-09 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-13 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-16 08:26:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3494.23, 349.42, 3843.65, 'Card', 'Paid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400072', 94, TO_TIMESTAMP('2024-02-25 03:59:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-01 03:59:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 1813.21, 181.32, 1994.53, 'Cash', 'Unpaid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400073', 40, TO_TIMESTAMP('2024-01-10 02:19:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-16 02:19:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-12 02:19:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 2084.36, 208.44, 2292.80, 'Cash', 'Paid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400074', 48, TO_TIMESTAMP('2024-01-01 14:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-08 14:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-06 14:49:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 824.26, 82.43, 906.69, 'Wire', 'Unpaid', 30, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400075', 86, TO_TIMESTAMP('2024-02-28 04:05:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-06 04:05:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-06 04:05:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 4236.00, 423.60, 4659.60, 'Cash', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400076', 99, TO_TIMESTAMP('2024-02-29 21:43:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-01 21:43:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-06 21:43:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2012.37, 201.24, 2213.61, 'Wire', 'Unpaid', 5, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400077', 68, TO_TIMESTAMP('2024-02-10 13:58:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-15 13:58:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-11 13:58:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 4971.15, 497.12, 5468.27, 'Wire', 'Paid', 32, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400078', 29, TO_TIMESTAMP('2024-01-07 15:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-13 15:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-10 15:39:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 4382.85, 438.29, 4821.14, 'Cash', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400079', 22, TO_TIMESTAMP('2024-02-13 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-23 10:00:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 2053.09, 205.31, 2258.40, 'Wire', 'Unpaid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400080', 81, TO_TIMESTAMP('2024-01-18 09:39:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-28 09:39:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 2482.42, 248.24, 2730.66, 'Wire', 'Paid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400081', 32, TO_TIMESTAMP('2024-02-22 11:23:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-03-03 11:23:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-25 11:23:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 3994.20, 399.42, 4393.62, 'Card', 'Unpaid', 40, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400082', 91, TO_TIMESTAMP('2024-02-13 04:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-17 04:04:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-19 04:04:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 486.88, 48.69, 535.57, 'Card', 'Paid', 49, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400083', 58, TO_TIMESTAMP('2024-01-17 20:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-19 20:49:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 2503.16, 250.32, 2753.48, 'Card', 'Unpaid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400084', 50, TO_TIMESTAMP('2024-02-07 19:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-15 19:33:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-12 19:33:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 2359.57, 235.96, 2595.53, 'Wire', 'Unpaid', 9, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400085', 42, TO_TIMESTAMP('2024-02-19 04:59:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-26 04:59:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-24 04:59:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 3347.16, 334.72, 3681.88, 'Card', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400086', 52, TO_TIMESTAMP('2024-02-11 09:17:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-12 09:17:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-16 09:17:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 730.93, 73.09, 804.02, 'Wire', 'Paid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400087', 38, TO_TIMESTAMP('2024-01-01 21:18:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-04 21:18:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 320.62, 32.06, 352.68, 'Card', 'Unpaid', 16, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400088', 98, TO_TIMESTAMP('2024-01-26 02:05:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-04 02:05:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 4199.44, 419.94, 4619.38, 'Cash', 'Unpaid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400089', 95, TO_TIMESTAMP('2024-01-25 20:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-02 20:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-27 20:49:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 334.62, 33.46, 368.08, 'Card', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400090', 40, TO_TIMESTAMP('2024-01-30 19:14:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-01 19:14:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-05 19:14:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2717.51, 271.75, 2989.26, 'Wire', 'Paid', 7, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400091', 4, TO_TIMESTAMP('2024-01-31 07:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-09 07:49:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-01 07:49:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 2954.92, 295.49, 3250.41, 'Cash', 'Paid', 38, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400092', 13, TO_TIMESTAMP('2024-02-19 03:34:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-22 03:34:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Shipped', 132.11, 13.21, 145.32, 'Wire', 'Paid', 15, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400093', 84, TO_TIMESTAMP('2024-02-18 10:35:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-24 10:35:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-25 10:35:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 2347.70, 234.77, 2582.47, 'Cash', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400094', 31, TO_TIMESTAMP('2024-02-14 09:42:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-15 09:42:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-19 09:42:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 4682.76, 468.28, 5151.04, 'Wire', 'Unpaid', 41, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400095', 20, TO_TIMESTAMP('2024-01-23 13:06:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-25 13:06:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-30 13:06:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 1989.45, 198.95, 2188.40, 'Cash', 'Unpaid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400096', 6, TO_TIMESTAMP('2024-01-03 19:13:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-01-06 19:13:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Pending', 1446.73, 144.67, 1591.40, 'Cash', 'Unpaid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400097', 28, TO_TIMESTAMP('2024-02-13 04:37:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-17 04:37:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-18 04:37:00', 'YYYY-MM-DD HH24:MI:SS'), 'Shipped', 4088.72, 408.87, 4497.59, 'Cash', 'Unpaid', 50, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400098', 82, TO_TIMESTAMP('2024-02-19 06:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-24 06:26:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-23 06:26:00', 'YYYY-MM-DD HH24:MI:SS'), 'Pending', 3316.53, 331.65, 3648.18, 'Card', 'Paid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400099', 89, TO_TIMESTAMP('2024-02-11 05:11:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-12 05:11:00', 'YYYY-MM-DD HH24:MI:SS'), NULL, 'Delivered', 295.75, 29.58, 325.33, 'Cash', 'Unpaid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400100', 72, TO_TIMESTAMP('2024-02-14 14:54:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-23 14:54:00', 'YYYY-MM-DD HH24:MI:SS'), TO_TIMESTAMP('2024-02-17 14:54:00', 'YYYY-MM-DD HH24:MI:SS'), 'Delivered', 4513.28, 451.33, 4964.61, 'Card', 'Paid', 12, NULL); --- OrderDetails (200 records) -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 29, 1777.50, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (80, 39, 264.67, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (18, 98, 17.43, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (73, 94, 1712.08, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (61, 97, 1440.42, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (98, 17, 31.18, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (30, 31, 1896.44, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (36, 13, 949.38, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (18, 84, 796.56, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (3, 43, 961.86, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (69, 39, 1799.64, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 71, 1823.86, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 54, 455.94, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 75, 1842.95, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 93, 201.11, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (46, 1, 918.59, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 53, 1020.11, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 27, 1195.89, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 76, 1550.34, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (78, 72, 1739.86, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (31, 90, 480.13, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (45, 35, 1684.24, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 81, 1497.70, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 24, 455.16, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (96, 71, 1597.44, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 73, 1566.61, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 29, 494.82, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (62, 68, 1124.58, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (36, 66, 888.46, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 43, 1034.76, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (51, 40, 517.71, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 30, 1905.53, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 27, 93.16, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (91, 13, 1342.39, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (77, 79, 910.75, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (33, 35, 1972.92, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 28, 102.12, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 95, 1203.14, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (35, 95, 1437.42, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (97, 80, 1686.56, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 66, 341.26, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (5, 7, 307.73, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 93, 626.23, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (26, 41, 1032.94, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 61, 536.34, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 27, 1599.35, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (73, 40, 1224.20, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 33, 1412.27, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (89, 7, 1285.65, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (44, 84, 1304.89, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (19, 83, 584.56, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (18, 56, 927.57, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 70, 1801.52, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 64, 1470.01, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (31, 33, 314.70, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (89, 17, 1853.16, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (73, 69, 1363.90, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (37, 38, 79.49, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (34, 22, 1974.09, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (44, 23, 1275.23, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (44, 17, 154.52, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 17, 1629.91, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 50, 1276.13, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 66, 926.53, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 76, 892.05, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (88, 94, 1380.40, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (90, 9, 1891.33, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (27, 90, 1257.24, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 88, 862.60, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (6, 37, 441.65, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (3, 73, 429.30, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (6, 79, 741.04, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (98, 28, 1073.84, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 1, 782.77, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (13, 49, 1928.68, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (23, 90, 1381.40, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (97, 100, 945.98, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (61, 22, 1038.04, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 48, 7.53, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 72, 96.63, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 98, 43.95, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (56, 53, 514.51, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (72, 95, 1237.99, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (92, 19, 88.61, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 64, 428.01, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 70, 1587.96, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 15, 592.58, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 70, 1682.21, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (90, 33, 679.70, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 40, 1561.75, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 25, 82.84, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (33, 14, 141.92, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (46, 58, 1905.97, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (15, 8, 573.35, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (18, 50, 274.44, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (77, 89, 769.08, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (95, 96, 1440.06, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (40, 89, 622.81, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (53, 62, 17.71, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (3, 16, 1199.34, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (75, 55, 1094.81, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (10, 39, 216.07, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (6, 36, 231.05, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (42, 9, 849.63, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 27, 1430.57, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (80, 59, 1486.91, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (53, 58, 738.40, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 54, 221.06, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (87, 61, 1590.57, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 72, 900.03, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (6, 80, 1956.50, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 54, 1591.68, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (32, 50, 1233.76, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 96, 912.45, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (33, 27, 130.11, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (7, 24, 787.75, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (35, 24, 1126.86, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 86, 1908.22, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 90, 938.59, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 87, 456.71, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 95, 1655.43, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 45, 212.33, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 56, 72.02, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (12, 32, 139.83, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 65, 1730.73, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (23, 49, 1701.35, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (58, 56, 272.27, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (75, 57, 493.78, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (46, 28, 1617.27, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 58, 875.32, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (1, 69, 997.85, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (59, 62, 534.02, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (29, 47, 1258.38, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (46, 73, 1085.84, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (19, 78, 1700.85, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (85, 19, 706.29, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (42, 83, 1355.04, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (99, 2, 886.60, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 94, 367.01, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 23, 730.64, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 49, 1971.79, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (19, 38, 578.90, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 99, 12.63, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (22, 94, 487.04, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (47, 48, 1925.40, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 5, 1590.29, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (100, 52, 1100.38, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (95, 72, 591.90, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 57, 749.66, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 59, 187.87, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (31, 29, 360.82, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (100, 47, 1438.76, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (1, 24, 1830.23, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (87, 18, 856.31, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 73, 17.03, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 7, 804.98, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (98, 2, 950.29, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 4, 946.51, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (8, 32, 727.68, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 39, 1472.74, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 78, 589.05, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (83, 78, 101.60, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 15, 201.32, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 42, 94.09, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (53, 44, 1327.46, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (51, 49, 1515.09, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 77, 22.39, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 58, 182.82, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 93, 306.08, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (69, 9, 1432.53, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 47, 1702.86, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 49, 1464.27, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 15, 981.52, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (26, 80, 645.89, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 81, 74.63, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 87, 1122.79, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (31, 60, 435.24, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (63, 10, 846.12, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 26, 1652.92, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 62, 1856.33, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (22, 70, 192.63, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (27, 44, 1023.46, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (53, 14, 323.18, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 32, 388.11, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (47, 35, 472.03, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (62, 54, 987.37, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (70, 96, 46.52, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (23, 67, 1053.78, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (56, 53, 1992.06, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (10, 43, 789.67, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (27, 98, 1115.01, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 46, 1829.05, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (95, 28, 1828.97, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 74, 377.65, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (42, 74, 788.33, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (72, 69, 1677.57, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (95, 54, 938.67, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (57, 15, 1571.23, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (35, 88, 383.50, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (91, 9, 1555.04, 3, 0.00); diff --git a/resources/sample_data_sqlite.sql b/resources/sample_data_sqlite.sql deleted file mode 100644 index f3ecc8e..0000000 --- a/resources/sample_data_sqlite.sql +++ /dev/null @@ -1,555 +0,0 @@ --- Customers (100 records) -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST001', '(주)한국전자', '김철수', '김철수@한국전자.co.kr', '02-4021-6058', '서울시 강남구', '서울', '서울', '대한민국', 'VIP', 29800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST002', '(주)서울무역상사', '이영희', '이영희@서울무역상사.co.kr', '02-2928-1011', '서울시 강남구', '부산', '부산', '대한민국', 'Premium', 187300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST003', '(주)부산산업', '박민수', '박민수@부산산업.co.kr', '02-5264-7815', '서울시 강남구', '대구', '대구', '대한민국', 'VIP', 57900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST004', '(주)대구섬유', '최지영', '최지영@대구섬유.co.kr', '02-4946-4844', '서울시 강남구', '인천', '인천', '대한민국', 'VIP', 90600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST005', '(주)인천물류센터', '정현우', '정현우@인천물류센터.co.kr', '02-4790-4006', '서울시 강남구', '광주', '광주', '대한민국', 'VIP', 56000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST006', '(주)광주식품유통', '강수진', '강수진@광주식품유통.co.kr', '02-5693-6316', '서울시 강남구', '대전', '대전', '대한민국', 'VIP', 179700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST007', '(주)제주특산물', '윤서연', '윤서연@제주특산물.co.kr', '02-1211-5112', '서울시 강남구', '울산', '울산', '대한민국', 'VIP', 149900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST008', '(주)울산화학공업', '임동혁', '임동혁@울산화학공업.co.kr', '02-9087-7480', '서울시 강남구', '제주', '제주', '대한민국', 'VIP', 125900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST009', '(주)대전기술연구소', '송미래', '송미래@대전기술연구소.co.kr', '02-8041-5691', '서울시 강남구', '수원', '경기', '대한민국', 'Regular', 79100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST010', '(주)경기통상', '한지훈', '한지훈@경기통상.co.kr', '02-9610-6582', '서울시 강남구', '성남', '강원', '대한민국', 'Premium', 146600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST011', '서울가구', '김영수', '김영수@서울가구.co.kr', '02-6434-2391', '서울시 강남구', '서울', '서울', '대한민국', 'VIP', 75300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST012', '부산수산', '이순희', '이순희@부산수산.co.kr', '02-2442-3769', '서울시 강남구', '부산', '부산', '대한민국', 'VIP', 97500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST013', '대구한방약품', '박건호', '박건호@대구한방약품.co.kr', '02-4187-4345', '서울시 강남구', '대구', '대구', '대한민국', 'Regular', 185900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST014', '인천해운', '최미영', '최미영@인천해운.co.kr', '02-6199-5824', '서울시 강남구', '인천', '인천', '대한민국', 'Regular', 194000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST015', '광주자동차부품', '정태윤', '정태윤@광주자동차부품.co.kr', '02-3746-6403', '서울시 강남구', '광주', '광주', '대한민국', 'Regular', 128900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST016', '제주관광개발', '강민석', '강민석@제주관광개발.co.kr', '02-2188-8561', '서울시 강남구', '대전', '대전', '대한민국', 'Premium', 125400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST017', '울산조선', '윤혜진', '윤혜진@울산조선.co.kr', '02-7843-1213', '서울시 강남구', '울산', '울산', '대한민국', 'VIP', 80100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST018', '대전바이오', '임재현', '임재현@대전바이오.co.kr', '02-2261-1215', '서울시 강남구', '제주', '제주', '대한민국', 'VIP', 96900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST019', '경기반도체', '송현주', '송현주@경기반도체.co.kr', '02-2302-2616', '서울시 강남구', '수원', '경기', '대한민국', 'Regular', 135800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST020', '서울패션', '한수연', '한수연@서울패션.co.kr', '02-2901-1177', '서울시 강남구', '성남', '강원', '대한민국', 'VIP', 29000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST021', '부산철강', '김동현', '김동현@부산철강.co.kr', '02-1729-4597', '서울시 강남구', '서울', '서울', '대한민국', 'Regular', 178200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST022', '대구섬유공업', '이지은', '이지은@대구섬유공업.co.kr', '02-8335-3840', '서울시 강남구', '부산', '부산', '대한민국', 'Regular', 127900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST023', '인천유리', '박상철', '박상철@인천유리.co.kr', '02-8857-8926', '서울시 강남구', '대구', '대구', '대한민국', 'VIP', 149200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST024', '광주전자부품', '최윤정', '최윤정@광주전자부품.co.kr', '02-3614-8464', '서울시 강남구', '인천', '인천', '대한민국', 'Regular', 197900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST025', '제주식품', '정수현', '정수현@제주식품.co.kr', '02-7122-6166', '서울시 강남구', '광주', '광주', '대한민국', 'VIP', 170400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST026', '울산정유', '강태영', '강태영@울산정유.co.kr', '02-4486-7913', '서울시 강남구', '대전', '대전', '대한민국', 'Premium', 38400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST027', '대전전자', '윤미선', '윤미선@대전전자.co.kr', '02-2079-8298', '서울시 강남구', '울산', '울산', '대한민국', 'Regular', 143100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST028', '경기화학', '임경호', '임경호@경기화학.co.kr', '02-7866-3765', '서울시 강남구', '제주', '제주', '대한민국', 'Regular', 100700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST029', '서울건설', '송재민', '송재민@서울건설.co.kr', '02-2561-1353', '서울시 강남구', '수원', '경기', '대한민국', 'Regular', 77000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST030', '부산건설자재', '한영미', '한영미@부산건설자재.co.kr', '02-6989-6566', '서울시 강남구', '성남', '강원', '대한민국', 'Regular', 38800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST031', '대구기계', '김민재', '김민재@대구기계.co.kr', '02-8563-1992', '서울시 강남구', '서울', '서울', '대한민국', 'Premium', 94700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST032', '인천항만', '이상훈', '이상훈@인천항만.co.kr', '02-1180-7909', '서울시 강남구', '부산', '부산', '대한민국', 'Regular', 148700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST033', '광주광산', '박정아', '박정아@광주광산.co.kr', '02-6629-4532', '서울시 강남구', '대구', '대구', '대한민국', 'VIP', 106900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST034', '제주에너지', '최승현', '최승현@제주에너지.co.kr', '02-3537-2308', '서울시 강남구', '인천', '인천', '대한민국', 'Premium', 73200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST035', '울산자동차', '정유진', '정유진@울산자동차.co.kr', '02-3368-3442', '서울시 강남구', '광주', '광주', '대한민국', 'Regular', 17200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST036', '대전소프트웨어', '강도현', '강도현@대전소프트웨어.co.kr', '02-4398-7419', '서울시 강남구', '대전', '대전', '대한민국', 'VIP', 32100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST037', '경기물류', '윤서준', '윤서준@경기물류.co.kr', '02-5277-9826', '서울시 강남구', '울산', '울산', '대한민국', 'Premium', 59300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST038', '서울의료기기', '임하은', '임하은@서울의료기기.co.kr', '02-4239-3211', '서울시 강남구', '제주', '제주', '대한민국', 'Regular', 110700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST039', '부산바이오', '송지우', '송지우@부산바이오.co.kr', '02-8286-2703', '서울시 강남구', '수원', '경기', '대한민국', 'VIP', 98500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST040', '대구IT', '한승우', '한승우@대구it.co.kr', '02-3150-1644', '서울시 강남구', '성남', '강원', '대한민국', 'Premium', 21800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST041', '인천신재생에너지', '김시우', '김시우@인천신재생에너지.co.kr', '02-9618-6693', '서울시 강남구', '서울', '서울', '대한민국', 'VIP', 164700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST042', '광주스마트팩토리', '이예은', '이예은@광주스마트팩토리.co.kr', '02-8599-4463', '서울시 강남구', '부산', '부산', '대한민국', 'VIP', 176600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST043', '제주데이터센터', '박하준', '박하준@제주데이터센터.co.kr', '02-2865-7646', '서울시 강남구', '대구', '대구', '대한민국', 'Premium', 64400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST044', '울산디스플레이', '최서윤', '최서윤@울산디스플레이.co.kr', '02-4888-6174', '서울시 강남구', '인천', '인천', '대한민국', 'Regular', 138200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST045', '대전우주항공', '정민재', '정민재@대전우주항공.co.kr', '02-8438-5811', '서울시 강남구', '광주', '광주', '대한민국', 'Regular', 100000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST046', '경기AI산업', '강유나', '강유나@경기ai산업.co.kr', '02-4674-9795', '서울시 강남구', '대전', '대전', '대한민국', 'VIP', 152600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST047', '서울핀테크', '윤도윤', '윤도윤@서울핀테크.co.kr', '02-1755-9725', '서울시 강남구', '울산', '울산', '대한민국', 'VIP', 189600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST048', '부산로봇산업', '임서준', '임서준@부산로봇산업.co.kr', '02-1559-1687', '서울시 강남구', '제주', '제주', '대한민국', 'Regular', 52600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST049', '대구드론', '송지안', '송지안@대구드론.co.kr', '02-8137-2640', '서울시 강남구', '수원', '경기', '대한민국', 'Premium', 119900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST050', '인천스마트시티', '한예진', '한예진@인천스마트시티.co.kr', '02-1077-1344', '서울시 강남구', '성남', '강원', '대한민국', 'Premium', 178500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST051', 'Tech Solutions Inc', 'John Smith', 'john@tech.com', '+1-555-1309', 'Address', 'San Francisco', 'State', 'USA', 'Premium', 187100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST053', 'Global Trading Co', 'Emily Johnson', 'emily@global.com', '+1-555-7519', 'Address', 'New York', 'State', 'USA', 'Premium', 219700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST055', 'Digital Innovations', 'Michael Brown', 'michael@digital.com', '+1-555-9751', 'Address', 'London', 'State', 'USA', 'VIP', 95400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST057', 'Advanced Manufacturing', 'Sarah Davis', 'sarah@advanced.com', '+1-555-3950', 'Address', 'Berlin', 'State', 'USA', 'Regular', 200000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST059', 'Pacific Logistics', 'David Wilson', 'david@pacific.com', '+1-555-4496', 'Address', 'Sydney', 'State', 'USA', 'VIP', 136100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST061', 'Euro Electronics', 'Sophie Martin', 'sophie@euro.com', '+1-555-9264', 'Address', 'Paris', 'State', 'USA', 'VIP', 213800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST063', 'Asia Pacific Trade', 'James Lee', 'james@asia.com', '+1-555-8185', 'Address', 'Singapore', 'State', 'USA', 'Premium', 112900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST065', 'Northern Industries', 'Emma Anderson', 'emma@northern.com', '+1-555-2047', 'Address', 'Stockholm', 'State', 'USA', 'VIP', 138100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST067', 'Smart Tech Corp', 'Oliver Taylor', 'oliver@smart.com', '+1-555-4821', 'Address', 'Austin', 'State', 'USA', 'VIP', 215500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST069', 'International Supply', 'Isabella Thomas', 'isabella@international.com', '+1-555-2887', 'Address', 'Toronto', 'State', 'USA', 'Regular', 204200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST071', 'Future Systems', 'William Jackson', 'william@future.com', '+1-555-5398', 'Address', 'Tokyo', 'State', 'USA', 'Regular', 153400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST073', 'Green Energy Ltd', 'Olivia White', 'olivia@green.com', '+1-555-9234', 'Address', 'Manchester', 'State', 'USA', 'Premium', 25400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST075', 'Advanced Materials', 'Ethan Harris', 'ethan@advanced.com', '+1-555-1318', 'Address', 'Munich', 'State', 'USA', 'Premium', 241600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST077', 'Ocean Freight Co', 'Ava Martinez', 'ava@ocean.com', '+1-555-7828', 'Address', 'Amsterdam', 'State', 'USA', 'VIP', 30300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST079', 'Digital Commerce', 'Noah Robinson', 'noah@digital.com', '+1-555-4760', 'Address', 'Seattle', 'State', 'USA', 'Premium', 49700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST081', 'Biotech Research', 'Mia Clark', 'mia@biotech.com', '+1-555-6928', 'Address', 'Zurich', 'State', 'USA', 'VIP', 39500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST083', 'Automotive Parts Ltd', 'Lucas Rodriguez', 'lucas@automotive.com', '+1-555-3961', 'Address', 'Milan', 'State', 'USA', 'Premium', 168100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST085', 'Cloud Services Inc', 'Charlotte Lewis', 'charlotte@cloud.com', '+1-555-6739', 'Address', 'Dublin', 'State', 'USA', 'VIP', 227700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST087', 'Pharma Solutions', 'Benjamin Walker', 'benjamin@pharma.com', '+1-555-2062', 'Address', 'Brussels', 'State', 'USA', 'VIP', 244300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST089', 'Robotics International', 'Amelia Hall', 'amelia@robotics.com', '+1-555-3085', 'Address', 'Seoul', 'State', 'USA', 'Regular', 161200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST091', 'Financial Systems', 'Henry Allen', 'henry@financial.com', '+1-555-9392', 'Address', 'Chicago', 'State', 'USA', 'Regular', 82700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST093', 'Renewable Power', 'Harper Young', 'harper@renewable.com', '+1-555-3411', 'Address', 'Copenhagen', 'State', 'USA', 'Premium', 96700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST095', 'Aerospace Tech', 'Alexander King', 'alexander@aerospace.com', '+1-555-5907', 'Address', 'Houston', 'State', 'USA', 'Regular', 43300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST097', 'Smart Agriculture', 'Evelyn Wright', 'evelyn@smart.com', '+1-555-5430', 'Address', 'Rotterdam', 'State', 'USA', 'Premium', 207600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST099', 'Quantum Computing', 'Sebastian Lopez', 'sebastian@quantum.com', '+1-555-6899', 'Address', 'Boston', 'State', 'USA', 'Premium', 90400000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST101', 'Marine Solutions', 'Ella Hill', 'ella@marine.com', '+1-555-1786', 'Address', 'Oslo', 'State', 'USA', 'VIP', 146200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST103', 'AI Development', 'Jack Scott', 'jack@ai.com', '+1-555-2567', 'Address', 'San Jose', 'State', 'USA', 'Premium', 62100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST105', 'Logistics Solutions', 'Aria Green', 'aria@logistics.com', '+1-555-3255', 'Address', 'Singapore', 'State', 'USA', 'VIP', 97300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST107', 'Construction Tech', 'Mason Adams', 'mason@construction.com', '+1-555-8822', 'Address', 'Melbourne', 'State', 'USA', 'Premium', 141600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST109', 'Food Processing', 'Luna Baker', 'luna@food.com', '+1-555-4349', 'Address', 'Madrid', 'State', 'USA', 'Regular', 243900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST111', 'Textile Manufacturing', 'Logan Nelson', 'logan@textile.com', '+1-555-1132', 'Address', 'Mumbai', 'State', 'USA', 'Regular', 164700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST113', 'Chemical Industries', 'Layla Carter', 'layla@chemical.com', '+1-555-5877', 'Address', 'São Paulo', 'State', 'USA', 'VIP', 120200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST115', 'Mining Corporation', 'Elijah Mitchell', 'elijah@mining.com', '+1-555-9114', 'Address', 'Johannesburg', 'State', 'USA', 'VIP', 79200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST117', 'Healthcare Systems', 'Chloe Perez', 'chloe@healthcare.com', '+1-555-3218', 'Address', 'Philadelphia', 'State', 'USA', 'Premium', 130900000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST119', 'Education Technology', 'Matthew Roberts', 'matthew@education.com', '+1-555-8084', 'Address', 'Edinburgh', 'State', 'USA', 'Regular', 129700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST121', 'Entertainment Media', 'Avery Turner', 'avery@entertainment.com', '+1-555-3058', 'Address', 'Los Angeles', 'State', 'USA', 'Premium', 62100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST123', 'Security Solutions', 'Daniel Phillips', 'daniel@security.com', '+1-555-9761', 'Address', 'Tel Aviv', 'State', 'USA', 'Regular', 115800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST125', 'Environmental Tech', 'Sofia Campbell', 'sofia@environmental.com', '+1-555-7552', 'Address', 'Helsinki', 'State', 'USA', 'Premium', 89300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST127', 'Transportation Systems', 'Joseph Parker', 'joseph@transportation.com', '+1-555-4164', 'Address', 'Vienna', 'State', 'USA', 'Regular', 214800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST129', 'Telecommunications', 'Victoria Evans', 'victoria@telecommunications.com', '+1-555-5288', 'Address', 'Hong Kong', 'State', 'USA', 'Premium', 230000000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST131', 'Water Treatment', 'David Edwards', 'david@water.com', '+1-555-6236', 'Address', 'Dubai', 'State', 'USA', 'Regular', 100100000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST133', 'Fashion Design', 'Grace Collins', 'grace@fashion.com', '+1-555-2158', 'Address', 'Paris', 'State', 'USA', 'Premium', 210700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST135', 'Gaming Studios', 'Samuel Stewart', 'samuel@gaming.com', '+1-555-1470', 'Address', 'San Francisco', 'State', 'USA', 'Regular', 156300000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST137', 'Space Technology', 'Zoe Sanchez', 'zoe@space.com', '+1-555-9614', 'Address', 'Cape Canaveral', 'State', 'USA', 'Premium', 192200000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST139', 'Furniture Design', 'Ryan Morris', 'ryan@furniture.com', '+1-555-3372', 'Address', 'Gothenburg', 'State', 'USA', 'Regular', 141500000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST141', 'Printing Services', 'Penelope Rogers', 'penelope@printing.com', '+1-555-5306', 'Address', 'Hamburg', 'State', 'USA', 'Premium', 230600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST143', 'Packaging Solutions', 'Isaac Reed', 'isaac@packaging.com', '+1-555-7184', 'Address', 'Atlanta', 'State', 'USA', 'VIP', 100800000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST145', 'Laboratory Equipment', 'Stella Cook', 'stella@laboratory.com', '+1-555-6289', 'Address', 'Basel', 'State', 'USA', 'Regular', 27600000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST147', 'Sports Equipment', 'Christian Morgan', 'christian@sports.com', '+1-555-7631', 'Address', 'Denver', 'State', 'USA', 'Regular', 221700000.00, 1); -INSERT INTO Customers (CustomerCode, CustomerName, ContactName, Email, Phone, Address, City, Region, Country, CustomerType, CreditLimit, IsActive) VALUES ('CUST149', 'Defense Systems', 'Nora Bell', 'nora@defense.com', '+1-555-7691', 'Address', 'Arlington', 'State', 'USA', 'VIP', 231600000.00, 1); --- Products (100 records) -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-100', '노트북', '전자제품', 1827.26, 422, 200, 33, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-101', '마우스', '전자제품', 769.60, 312, 109, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-102', '키보드', '전자제품', 1648.32, 270, 36, 48, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-103', '모니터', '전자제품', 167.54, 193, 53, 31, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-104', '외장 SSD', '저장장치', 97.38, 445, 198, 3, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-105', 'USB 메모리', '저장장치', 1683.07, 382, 185, 48, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-106', '이어폰', '오디오', 1352.69, 61, 111, 20, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-107', '스피커', '오디오', 1094.56, 383, 21, 33, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-108', '웹캠', '전자제품', 1179.36, 218, 171, 42, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-109', '태블릿', '전자제품', 511.12, 292, 91, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-110', '프린터', '사무기기', 1704.46, 343, 21, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-111', '복합기', '사무기기', 1832.13, 295, 103, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-112', '스탠드', '사무용품', 1183.88, 240, 132, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-113', '의자', '가구', 981.16, 191, 117, 13, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-114', '캐비닛', '가구', 279.05, 269, 60, 46, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-115', '책상', '가구', 971.59, 489, 19, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-116', '램프', '사무용품', 50.48, 60, 191, 39, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-117', '충전기', '전자제품', 969.30, 422, 149, 17, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-118', '케이블', '전자제품', 1337.00, 51, 73, 46, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-119', '허브', '전자제품', 438.10, 437, 22, 34, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-120', '헤드셋', '오디오', 1766.40, 120, 65, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-121', '마이크', '오디오', 383.99, 439, 126, 24, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-122', '스캐너', '사무기기', 1447.91, 414, 163, 19, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-123', '라벨기', '사무기기', 1747.45, 337, 79, 5, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-124', '계산기', '사무용품', 1552.30, 121, 10, 34, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-125', '화이트보드', '사무용품', 634.70, 192, 183, 3, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-126', '복사기', '사무기기', 1028.11, 194, 137, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-127', '파쇄기', '사무기기', 1443.76, 397, 4, 10, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-128', '바인더', '사무용품', 1760.18, 356, 113, 41, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-129', '필기구', '사무용품', 772.73, 208, 82, 36, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-130', '노트', '사무용품', 1252.52, 439, 169, 31, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-131', '파일', '사무용품', 155.03, 15, 65, 15, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-132', '클립', '사무용품', 1298.84, 228, 171, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-133', '테이프', '사무용품', 830.42, 299, 101, 16, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-134', '가위', '사무용품', 771.34, 296, 159, 20, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-135', '스테이플러', '사무용품', 533.56, 303, 194, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-136', '펀치', '사무용품', 1048.76, 29, 30, 31, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-137', '자', '사무용품', 423.68, 77, 170, 10, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-138', '형광펜', '사무용품', 1358.90, 340, 13, 45, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-139', '지우개', '사무용품', 776.80, 449, 161, 0, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-140', '수정테이프', '사무용품', 1315.13, 260, 20, 44, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-141', '포스트잇', '사무용품', 764.28, 423, 149, 41, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-142', '달력', '사무용품', 669.79, 461, 8, 20, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-143', '플래너', '사무용품', 493.41, 196, 114, 2, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-144', '시계', '사무용품', 1022.73, 329, 182, 22, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-145', '쓰레기통', '사무용품', 1975.61, 181, 187, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-146', '우산꽂이', '사무용품', 1683.54, 19, 21, 39, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-147', '신발장', '가구', 1106.55, 416, 150, 34, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-148', '사물함', '가구', 1466.23, 74, 5, 17, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-149', '칸막이', '가구', 1825.13, 477, 33, 6, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-200', 'Laptop Computer', 'Electronics', 1373.62, 345, 124, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-201', 'Wireless Mouse', 'Electronics', 145.80, 435, 165, 10, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-202', 'Mechanical Keyboard', 'Electronics', 526.20, 308, 159, 42, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-203', 'Monitor 27inch', 'Electronics', 1202.70, 198, 38, 29, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-204', 'External SSD', 'Storage', 1623.21, 282, 123, 3, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-205', 'USB Flash Drive', 'Storage', 1449.61, 125, 70, 26, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-206', 'Wireless Earbuds', 'Audio', 1016.97, 412, 93, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-207', 'Bluetooth Speaker', 'Audio', 604.62, 438, 120, 46, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-208', 'HD Webcam', 'Electronics', 1426.00, 487, 69, 24, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-209', 'Tablet Device', 'Electronics', 1925.41, 87, 121, 11, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-210', 'Laser Printer', 'Office Equipment', 307.42, 482, 37, 20, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-211', 'Multifunction Printer', 'Office Equipment', 121.09, 135, 6, 18, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-212', 'Desk Lamp', 'Office Supplies', 307.27, 227, 49, 50, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-213', 'Office Chair', 'Furniture', 1642.82, 490, 115, 1, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-214', 'File Cabinet', 'Furniture', 1265.18, 59, 188, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-215', 'Standing Desk', 'Furniture', 1473.31, 224, 23, 17, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-216', 'LED Lamp', 'Office Supplies', 1506.30, 483, 28, 18, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-217', 'Power Adapter', 'Electronics', 1889.15, 49, 87, 23, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-218', 'USB Cable', 'Electronics', 1112.73, 231, 65, 19, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-219', 'USB Hub', 'Electronics', 1738.63, 334, 151, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-220', 'Gaming Headset', 'Audio', 1206.77, 374, 154, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-221', 'Studio Microphone', 'Audio', 844.00, 60, 28, 33, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-222', 'Document Scanner', 'Office Equipment', 1721.46, 267, 59, 23, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-223', 'Label Printer', 'Office Equipment', 354.27, 189, 167, 34, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-224', 'Calculator', 'Office Supplies', 291.31, 279, 41, 5, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-225', 'Whiteboard', 'Office Supplies', 175.79, 342, 128, 12, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-226', 'Copier', 'Office Equipment', 787.74, 356, 115, 18, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-227', 'Paper Shredder', 'Office Equipment', 1515.46, 300, 73, 44, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-228', 'Ring Binder', 'Office Supplies', 209.28, 204, 193, 28, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-229', 'Pen Set', 'Office Supplies', 1199.59, 276, 171, 21, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-230', 'Notebook', 'Office Supplies', 1436.46, 431, 90, 7, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-231', 'File Folder', 'Office Supplies', 1709.30, 323, 145, 49, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-232', 'Paper Clips', 'Office Supplies', 1425.04, 277, 3, 18, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-233', 'Adhesive Tape', 'Office Supplies', 974.62, 393, 200, 50, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-234', 'Scissors', 'Office Supplies', 862.18, 178, 12, 24, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-235', 'Stapler', 'Office Supplies', 1562.15, 110, 51, 44, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-236', 'Hole Punch', 'Office Supplies', 358.08, 58, 63, 30, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-237', 'Ruler Set', 'Office Supplies', 880.64, 84, 78, 15, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-238', 'Highlighter', 'Office Supplies', 1656.33, 433, 159, 40, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-239', 'Eraser', 'Office Supplies', 422.10, 83, 142, 45, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-240', 'Correction Tape', 'Office Supplies', 1521.60, 483, 121, 43, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-241', 'Sticky Notes', 'Office Supplies', 260.11, 405, 158, 50, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-242', 'Wall Calendar', 'Office Supplies', 1345.97, 260, 200, 35, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-243', 'Daily Planner', 'Office Supplies', 1465.90, 281, 116, 38, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-244', 'Wall Clock', 'Office Supplies', 1045.58, 14, 41, 50, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-245', 'Waste Bin', 'Office Supplies', 1228.59, 210, 168, 13, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-246', 'Umbrella Stand', 'Office Supplies', 682.56, 285, 12, 36, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-247', 'Shoe Rack', 'Furniture', 1764.87, 51, 18, 12, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-248', 'Storage Locker', 'Furniture', 1755.38, 494, 195, 36, 0, NULL); -INSERT INTO Products (ProductCode, ProductName, Category, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued, Description) VALUES ('P-249', 'Privacy Screen', 'Furniture', 587.29, 314, 118, 14, 0, NULL); --- Employees (50 records) -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-001', 'Alice', 'Jung', 'Engineer', '2006-06-06', '2023-01-25', 'alice.jung@example.com', '010-5635-7386', 'Sales', 7930.36, NULL, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-002', 'Evan', 'Jung', 'Assistant', '1978-09-12', '2022-06-18', 'evan.jung@example.com', '010-2922-3754', 'HR', 5474.01, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-003', 'Cathy', 'Kang', 'Director', '2014-07-19', '2022-03-12', 'cathy.kang@example.com', '010-6054-1578', 'Finance', 6105.26, 2, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-004', 'Brian', 'Jung', 'Assistant', '2001-06-28', '2017-05-04', 'brian.jung@example.com', '010-9764-7907', 'IT', 5112.65, 3, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-005', 'Ian', 'Han', 'Engineer', '2008-11-08', '2025-01-13', 'ian.han@example.com', '010-7744-9406', 'Finance', 4799.35, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-006', 'Alice', 'Song', 'Manager', '2023-12-31', '2022-04-11', 'alice.song@example.com', '010-2457-3542', 'HR', 4439.73, 5, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-007', 'David', 'Song', 'Engineer', '1978-04-06', '2025-03-06', 'david.song@example.com', '010-4437-9487', 'Marketing', 7628.69, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-008', 'Alice', 'Jung', 'Engineer', '1982-11-07', '2024-07-04', 'alice.jung@example.com', '010-9144-1401', 'HR', 7374.32, 2, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-009', 'George', 'Lim', 'Engineer', '1996-10-28', '2021-07-26', 'george.lim@example.com', '010-1441-3951', 'HR', 4863.87, 6, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-010', 'Cathy', 'Song', 'Engineer', '1988-06-23', '2024-12-03', 'cathy.song@example.com', '010-7588-6976', 'Sales', 8020.20, 5, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-011', 'Alice', 'Kim', 'Engineer', '1985-10-18', '2019-04-29', 'alice.kim@example.com', '010-6805-2139', 'Finance', 7110.12, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-012', 'Fiona', 'Jung', 'Analyst', '1986-03-05', '2017-06-28', 'fiona.jung@example.com', '010-3161-7466', 'Marketing', 4948.90, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-013', 'David', 'Han', 'Manager', '1986-11-17', '2024-11-15', 'david.han@example.com', '010-9456-2556', 'HR', 5702.20, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-014', 'Alice', 'Lim', 'Engineer', '1998-06-12', '2015-12-16', 'alice.lim@example.com', '010-9505-6270', 'Sales', 6761.58, 5, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-015', 'George', 'Park', 'Director', '1985-11-30', '2019-10-28', 'george.park@example.com', '010-2055-6508', 'Sales', 8507.28, 5, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-016', 'George', 'Yoon', 'Analyst', '1976-12-13', '2024-12-21', 'george.yoon@example.com', '010-9637-9396', 'Finance', 7624.27, 2, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-017', 'Fiona', 'Jung', 'Director', '1976-06-15', '2015-12-20', 'fiona.jung@example.com', '010-9765-4442', 'IT', 8234.76, 13, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-018', 'David', 'Kang', 'Manager', '1999-06-17', '2017-02-09', 'david.kang@example.com', '010-6800-6650', 'Finance', 3392.19, 6, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-019', 'Alice', 'Han', 'Engineer', '1999-07-04', '2020-08-31', 'alice.han@example.com', '010-5611-3033', 'Marketing', 3618.45, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-020', 'David', 'Kang', 'Manager', '1995-12-21', '2022-10-17', 'david.kang@example.com', '010-1487-6423', 'Sales', 7037.84, 15, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-021', 'Ian', 'Kang', 'Director', '2018-11-30', '2025-07-09', 'ian.kang@example.com', '010-8744-4509', 'Sales', 6052.89, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-022', 'George', 'Kim', 'Assistant', '1979-10-03', '2020-10-21', 'george.kim@example.com', '010-5134-1787', 'Marketing', 5737.19, 4, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-023', 'Julia', 'Lee', 'Analyst', '1989-04-08', '2020-01-03', 'julia.lee@example.com', '010-1623-9554', 'HR', 5945.21, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-024', 'Ian', 'Park', 'Analyst', '1993-03-27', '2020-01-19', 'ian.park@example.com', '010-5447-6404', 'IT', 3257.24, 18, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-025', 'Evan', 'Choi', 'Manager', '2001-05-29', '2018-02-19', 'evan.choi@example.com', '010-2840-5905', 'HR', 8856.74, 6, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-026', 'Julia', 'Han', 'Assistant', '2017-02-22', '2021-08-30', 'julia.han@example.com', '010-9922-4331', 'Finance', 4760.03, 11, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-027', 'George', 'Jung', 'Analyst', '1975-07-04', '2019-12-15', 'george.jung@example.com', '010-1910-4736', 'IT', 3021.27, 23, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-028', 'Alice', 'Kim', 'Director', '1971-04-17', '2016-07-23', 'alice.kim@example.com', '010-3440-1886', 'Marketing', 8682.97, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-029', 'Brian', 'Song', 'Assistant', '2023-07-13', '2018-03-01', 'brian.song@example.com', '010-7408-5590', 'IT', 8535.49, 22, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-030', 'Ian', 'Kang', 'Manager', '2021-08-23', '2024-03-29', 'ian.kang@example.com', '010-4138-9382', 'Sales', 3756.16, 19, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-031', 'Fiona', 'Yoon', 'Manager', '1986-04-09', '2025-08-02', 'fiona.yoon@example.com', '010-2037-4376', 'Sales', 7506.28, 14, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-032', 'George', 'Park', 'Director', '1987-10-05', '2024-10-26', 'george.park@example.com', '010-7917-8592', 'Marketing', 4271.54, 25, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-033', 'Evan', 'Lee', 'Engineer', '1994-03-07', '2024-03-03', 'evan.lee@example.com', '010-1199-3822', 'Marketing', 5055.58, 13, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-034', 'Julia', 'Kim', 'Engineer', '1990-04-24', '2024-05-26', 'julia.kim@example.com', '010-2815-7789', 'HR', 6362.28, 17, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-035', 'Cathy', 'Kim', 'Manager', '1978-07-20', '2019-04-23', 'cathy.kim@example.com', '010-7347-1304', 'Finance', 4193.36, 18, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-036', 'Ian', 'Lim', 'Director', '2010-02-02', '2017-06-23', 'ian.lim@example.com', '010-3550-1757', 'IT', 3035.17, 28, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-037', 'Brian', 'Lim', 'Analyst', '2009-01-10', '2021-09-27', 'brian.lim@example.com', '010-5996-1835', 'Sales', 8670.13, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-038', 'Fiona', 'Lim', 'Engineer', '1972-05-07', '2020-10-18', 'fiona.lim@example.com', '010-7882-7766', 'Marketing', 4056.85, 1, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-039', 'David', 'Choi', 'Engineer', '1987-02-09', '2023-03-21', 'david.choi@example.com', '010-6000-5654', 'IT', 8907.89, 10, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-040', 'Alice', 'Choi', 'Director', '2004-03-11', '2020-11-12', 'alice.choi@example.com', '010-8139-6529', 'Finance', 3707.20, 30, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-041', 'Julia', 'Choi', 'Manager', '2001-10-06', '2023-12-25', 'julia.choi@example.com', '010-3679-1266', 'Sales', 7421.76, 16, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-042', 'Cathy', 'Jung', 'Director', '2010-05-05', '2016-01-27', 'cathy.jung@example.com', '010-5838-8561', 'Marketing', 7643.01, 26, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-043', 'Julia', 'Park', 'Analyst', '2015-03-23', '2025-09-14', 'julia.park@example.com', '010-8945-4807', 'Finance', 6192.98, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-044', 'Brian', 'Choi', 'Analyst', '1991-02-08', '2025-06-13', 'brian.choi@example.com', '010-7374-4731', 'Finance', 7228.98, 40, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-045', 'Ian', 'Kim', 'Director', '2008-10-17', '2018-09-20', 'ian.kim@example.com', '010-2828-8775', 'Finance', 8443.93, 20, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-046', 'Julia', 'Kim', 'Analyst', '2017-09-12', '2024-09-08', 'julia.kim@example.com', '010-8839-7782', 'Finance', 4302.86, 12, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-047', 'Fiona', 'Choi', 'Manager', '1986-08-17', '2020-09-17', 'fiona.choi@example.com', '010-9763-2885', 'Sales', 5451.62, 17, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-048', 'Julia', 'Park', 'Analyst', '2002-06-18', '2021-08-08', 'julia.park@example.com', '010-8289-3373', 'Marketing', 3991.62, 40, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-049', 'Ian', 'Song', 'Assistant', '2008-07-18', '2023-10-25', 'ian.song@example.com', '010-4084-7005', 'Marketing', 7750.14, 37, 1); -INSERT INTO Employees (EmployeeCode, FirstName, LastName, Title, BirthDate, HireDate, Email, Phone, Department, Salary, ReportsTo, IsActive) VALUES ('E-050', 'Fiona', 'Yoon', 'Director', '2011-01-11', '2016-03-01', 'fiona.yoon@example.com', '010-8149-9442', 'HR', 8666.88, 45, 1); --- Orders (100 records) -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400001', 9, '2024-02-21 07:13:00', '2024-03-02 07:13:00', '2024-02-26 07:13:00', 'Shipped', 4700.79, 470.08, 5170.87, 'Card', 'Unpaid', 33, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400002', 25, '2024-02-06 05:38:00', '2024-02-14 05:38:00', '2024-02-09 05:38:00', 'Shipped', 3413.93, 341.39, 3755.32, 'Cash', 'Unpaid', 14, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400003', 45, '2024-01-21 16:14:00', '2024-01-25 16:14:00', NULL, 'Pending', 653.85, 65.39, 719.24, 'Card', 'Unpaid', 32, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400004', 4, '2024-01-28 14:21:00', '2024-02-05 14:21:00', '2024-02-01 14:21:00', 'Pending', 2986.83, 298.68, 3285.51, 'Wire', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400005', 88, '2024-02-17 18:39:00', '2024-02-20 18:39:00', NULL, 'Delivered', 4534.78, 453.48, 4988.26, 'Cash', 'Paid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400006', 34, '2024-02-20 06:54:00', '2024-02-27 06:54:00', NULL, 'Shipped', 3713.91, 371.39, 4085.30, 'Wire', 'Paid', 11, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400007', 19, '2024-02-19 14:22:00', '2024-02-24 14:22:00', NULL, 'Shipped', 1489.10, 148.91, 1638.01, 'Card', 'Paid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400008', 69, '2024-01-26 03:44:00', '2024-02-04 03:44:00', '2024-02-02 03:44:00', 'Pending', 734.07, 73.41, 807.48, 'Wire', 'Paid', 18, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400009', 100, '2024-02-11 14:42:00', '2024-02-16 14:42:00', '2024-02-18 14:42:00', 'Pending', 4835.36, 483.54, 5318.90, 'Wire', 'Paid', 12, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400010', 51, '2024-02-17 06:26:00', '2024-02-25 06:26:00', '2024-02-19 06:26:00', 'Pending', 1171.53, 117.15, 1288.68, 'Wire', 'Unpaid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400011', 90, '2024-02-27 02:42:00', '2024-03-04 02:42:00', '2024-03-05 02:42:00', 'Pending', 298.65, 29.86, 328.51, 'Cash', 'Unpaid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400012', 80, '2024-01-19 14:41:00', '2024-01-29 14:41:00', '2024-01-20 14:41:00', 'Shipped', 2496.57, 249.66, 2746.23, 'Cash', 'Paid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400013', 56, '2024-01-26 03:55:00', '2024-01-30 03:55:00', '2024-02-02 03:55:00', 'Shipped', 3284.62, 328.46, 3613.08, 'Cash', 'Paid', 38, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400014', 79, '2024-02-09 03:24:00', '2024-02-10 03:24:00', '2024-02-10 03:24:00', 'Shipped', 1983.90, 198.39, 2182.29, 'Cash', 'Paid', 11, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400015', 91, '2024-01-07 22:00:00', '2024-01-13 22:00:00', '2024-01-12 22:00:00', 'Delivered', 663.68, 66.37, 730.05, 'Card', 'Paid', 41, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400016', 14, '2024-02-20 09:03:00', '2024-02-27 09:03:00', '2024-02-27 09:03:00', 'Delivered', 4310.03, 431.00, 4741.03, 'Card', 'Unpaid', 18, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400017', 84, '2024-02-06 12:42:00', '2024-02-13 12:42:00', '2024-02-08 12:42:00', 'Pending', 623.90, 62.39, 686.29, 'Wire', 'Paid', 30, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400018', 66, '2024-02-04 13:06:00', '2024-02-10 13:06:00', '2024-02-08 13:06:00', 'Shipped', 3969.40, 396.94, 4366.34, 'Wire', 'Paid', 16, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400019', 78, '2024-02-06 16:33:00', '2024-02-07 16:33:00', '2024-02-13 16:33:00', 'Pending', 596.66, 59.67, 656.33, 'Card', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400020', 96, '2024-01-24 17:45:00', '2024-01-27 17:45:00', '2024-01-30 17:45:00', 'Shipped', 1702.71, 170.27, 1872.98, 'Cash', 'Paid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400021', 64, '2024-01-27 18:42:00', '2024-02-04 18:42:00', '2024-02-01 18:42:00', 'Shipped', 4639.90, 463.99, 5103.89, 'Card', 'Paid', 42, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400022', 19, '2024-02-23 18:08:00', '2024-02-24 18:08:00', '2024-02-29 18:08:00', 'Shipped', 54.48, 5.45, 59.93, 'Card', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400023', 25, '2024-01-28 01:07:00', '2024-02-05 01:07:00', NULL, 'Delivered', 2775.92, 277.59, 3053.51, 'Wire', 'Paid', 29, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400024', 12, '2024-02-29 05:18:00', '2024-03-04 05:18:00', '2024-03-02 05:18:00', 'Pending', 225.78, 22.58, 248.36, 'Card', 'Paid', 28, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400025', 1, '2024-01-26 17:56:00', '2024-01-27 17:56:00', '2024-01-28 17:56:00', 'Pending', 4650.09, 465.01, 5115.10, 'Card', 'Paid', 29, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400026', 90, '2024-02-07 00:16:00', '2024-02-08 00:16:00', '2024-02-10 00:16:00', 'Delivered', 2999.02, 299.90, 3298.92, 'Card', 'Unpaid', 6, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400027', 53, '2024-03-01 18:39:00', '2024-03-03 18:39:00', '2024-03-03 18:39:00', 'Shipped', 3071.88, 307.19, 3379.07, 'Wire', 'Unpaid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400028', 56, '2024-02-16 01:53:00', '2024-02-18 01:53:00', '2024-02-19 01:53:00', 'Delivered', 2572.51, 257.25, 2829.76, 'Cash', 'Unpaid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400029', 33, '2024-02-26 16:02:00', '2024-03-03 16:02:00', '2024-02-28 16:02:00', 'Delivered', 4000.49, 400.05, 4400.54, 'Wire', 'Unpaid', 44, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400030', 5, '2024-02-28 20:35:00', '2024-03-02 20:35:00', '2024-03-06 20:35:00', 'Pending', 4346.46, 434.65, 4781.11, 'Cash', 'Paid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400031', 1, '2024-02-09 01:00:00', '2024-02-13 01:00:00', '2024-02-10 01:00:00', 'Delivered', 2267.64, 226.76, 2494.40, 'Card', 'Paid', 28, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400032', 42, '2024-02-08 16:33:00', '2024-02-14 16:33:00', NULL, 'Pending', 3028.88, 302.89, 3331.77, 'Cash', 'Paid', 44, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400033', 43, '2024-02-01 22:41:00', '2024-02-04 22:41:00', NULL, 'Delivered', 632.96, 63.30, 696.26, 'Cash', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400034', 77, '2024-02-18 14:50:00', '2024-02-28 14:50:00', '2024-02-24 14:50:00', 'Delivered', 299.17, 29.92, 329.09, 'Wire', 'Unpaid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400035', 67, '2024-01-09 07:45:00', '2024-01-10 07:45:00', NULL, 'Delivered', 3952.12, 395.21, 4347.33, 'Cash', 'Paid', 42, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400036', 98, '2024-02-20 12:22:00', '2024-02-25 12:22:00', NULL, 'Pending', 422.22, 42.22, 464.44, 'Card', 'Unpaid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400037', 17, '2024-01-19 15:33:00', '2024-01-24 15:33:00', '2024-01-23 15:33:00', 'Delivered', 4614.05, 461.41, 5075.46, 'Card', 'Unpaid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400038', 59, '2024-02-25 15:08:00', '2024-02-28 15:08:00', '2024-02-29 15:08:00', 'Shipped', 1632.36, 163.24, 1795.60, 'Cash', 'Unpaid', 17, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400039', 46, '2024-01-31 15:55:00', '2024-02-02 15:55:00', '2024-02-06 15:55:00', 'Pending', 4074.50, 407.45, 4481.95, 'Card', 'Paid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400040', 17, '2024-01-04 13:31:00', '2024-01-05 13:31:00', '2024-01-09 13:31:00', 'Pending', 2318.60, 231.86, 2550.46, 'Cash', 'Paid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400041', 14, '2024-02-15 10:03:00', '2024-02-24 10:03:00', '2024-02-22 10:03:00', 'Shipped', 1424.90, 142.49, 1567.39, 'Wire', 'Paid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400042', 68, '2024-01-23 09:50:00', '2024-01-31 09:50:00', '2024-01-24 09:50:00', 'Delivered', 2931.18, 293.12, 3224.30, 'Cash', 'Paid', 2, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400043', 11, '2024-01-30 19:32:00', '2024-01-31 19:32:00', '2024-02-05 19:32:00', 'Shipped', 1411.75, 141.18, 1552.93, 'Cash', 'Unpaid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400044', 61, '2024-01-17 05:08:00', '2024-01-23 05:08:00', '2024-01-22 05:08:00', 'Shipped', 2616.54, 261.65, 2878.19, 'Card', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400045', 44, '2024-01-18 02:36:00', '2024-01-23 02:36:00', '2024-01-19 02:36:00', 'Delivered', 2423.76, 242.38, 2666.14, 'Wire', 'Paid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400046', 87, '2024-02-18 17:06:00', '2024-02-24 17:06:00', '2024-02-21 17:06:00', 'Shipped', 2350.67, 235.07, 2585.74, 'Card', 'Unpaid', 5, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400047', 90, '2024-03-01 10:07:00', '2024-03-04 10:07:00', '2024-03-02 10:07:00', 'Shipped', 704.20, 70.42, 774.62, 'Wire', 'Paid', 37, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400048', 14, '2024-01-25 11:44:00', '2024-01-26 11:44:00', '2024-01-29 11:44:00', 'Delivered', 2783.38, 278.34, 3061.72, 'Wire', 'Paid', 50, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400049', 62, '2024-02-24 05:40:00', '2024-03-02 05:40:00', '2024-03-01 05:40:00', 'Shipped', 245.86, 24.59, 270.45, 'Card', 'Paid', 11, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400050', 47, '2024-01-21 15:22:00', '2024-01-31 15:22:00', NULL, 'Delivered', 3648.30, 364.83, 4013.13, 'Card', 'Unpaid', 4, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400051', 34, '2024-01-19 09:52:00', '2024-01-20 09:52:00', '2024-01-21 09:52:00', 'Pending', 3346.13, 334.61, 3680.74, 'Card', 'Unpaid', 8, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400052', 22, '2024-01-10 19:26:00', '2024-01-20 19:26:00', NULL, 'Delivered', 2370.97, 237.10, 2608.07, 'Cash', 'Paid', 22, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400053', 54, '2024-02-05 10:14:00', '2024-02-11 10:14:00', '2024-02-07 10:14:00', 'Delivered', 1069.94, 106.99, 1176.93, 'Wire', 'Paid', 9, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400054', 90, '2024-01-21 05:00:00', '2024-01-28 05:00:00', '2024-01-27 05:00:00', 'Delivered', 972.22, 97.22, 1069.44, 'Cash', 'Unpaid', 46, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400055', 97, '2024-02-11 12:37:00', '2024-02-16 12:37:00', NULL, 'Delivered', 2371.31, 237.13, 2608.44, 'Wire', 'Unpaid', 32, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400056', 52, '2024-01-05 11:34:00', '2024-01-06 11:34:00', '2024-01-11 11:34:00', 'Delivered', 452.29, 45.23, 497.52, 'Card', 'Paid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400057', 61, '2024-02-17 06:30:00', '2024-02-20 06:30:00', NULL, 'Pending', 2807.80, 280.78, 3088.58, 'Card', 'Unpaid', 20, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400058', 16, '2024-01-07 00:13:00', '2024-01-11 00:13:00', '2024-01-10 00:13:00', 'Delivered', 3558.36, 355.84, 3914.20, 'Cash', 'Unpaid', 32, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400059', 18, '2024-02-18 09:36:00', '2024-02-20 09:36:00', '2024-02-19 09:36:00', 'Shipped', 3291.96, 329.20, 3621.16, 'Card', 'Unpaid', 37, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400060', 72, '2024-02-11 20:09:00', '2024-02-14 20:09:00', '2024-02-17 20:09:00', 'Delivered', 2331.34, 233.13, 2564.47, 'Cash', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400061', 57, '2024-01-16 05:02:00', '2024-01-17 05:02:00', '2024-01-17 05:02:00', 'Pending', 1666.26, 166.63, 1832.89, 'Card', 'Unpaid', 14, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400062', 84, '2024-01-24 08:02:00', '2024-01-30 08:02:00', '2024-01-27 08:02:00', 'Shipped', 54.53, 5.45, 59.98, 'Card', 'Paid', 15, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400063', 16, '2024-02-05 04:14:00', '2024-02-06 04:14:00', '2024-02-10 04:14:00', 'Pending', 2490.69, 249.07, 2739.76, 'Cash', 'Unpaid', 13, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400064', 43, '2024-01-07 16:56:00', '2024-01-14 16:56:00', '2024-01-13 16:56:00', 'Delivered', 2172.74, 217.27, 2390.01, 'Cash', 'Unpaid', 29, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400065', 22, '2024-01-17 11:36:00', '2024-01-23 11:36:00', '2024-01-23 11:36:00', 'Shipped', 4191.98, 419.20, 4611.18, 'Card', 'Paid', 44, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400066', 3, '2024-02-17 04:01:00', '2024-02-27 04:01:00', NULL, 'Pending', 3019.94, 301.99, 3321.93, 'Card', 'Paid', 1, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400067', 78, '2024-01-31 17:36:00', '2024-02-08 17:36:00', '2024-02-05 17:36:00', 'Pending', 4571.70, 457.17, 5028.87, 'Cash', 'Unpaid', 6, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400068', 32, '2024-02-11 01:11:00', '2024-02-15 01:11:00', NULL, 'Shipped', 476.20, 47.62, 523.82, 'Cash', 'Unpaid', 10, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400069', 88, '2024-01-01 10:25:00', '2024-01-09 10:25:00', '2024-01-07 10:25:00', 'Shipped', 743.56, 74.36, 817.92, 'Wire', 'Unpaid', 3, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400070', 69, '2024-02-09 22:30:00', '2024-02-19 22:30:00', '2024-02-16 22:30:00', 'Delivered', 3578.79, 357.88, 3936.67, 'Cash', 'Unpaid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400071', 63, '2024-01-20 14:40:00', '2024-01-23 14:40:00', '2024-01-24 14:40:00', 'Pending', 3061.31, 306.13, 3367.44, 'Cash', 'Unpaid', 38, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400072', 51, '2024-01-17 08:49:00', '2024-01-23 08:49:00', '2024-01-23 08:49:00', 'Pending', 3657.64, 365.76, 4023.40, 'Wire', 'Paid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400073', 75, '2024-01-08 05:40:00', '2024-01-09 05:40:00', '2024-01-15 05:40:00', 'Pending', 642.10, 64.21, 706.31, 'Cash', 'Paid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400074', 80, '2024-02-17 05:18:00', '2024-02-19 05:18:00', '2024-02-24 05:18:00', 'Delivered', 333.06, 33.31, 366.37, 'Wire', 'Paid', 39, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400075', 72, '2024-02-06 01:02:00', '2024-02-16 01:02:00', '2024-02-08 01:02:00', 'Shipped', 2622.97, 262.30, 2885.27, 'Wire', 'Paid', 18, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400076', 46, '2024-02-21 01:14:00', '2024-02-27 01:14:00', '2024-02-27 01:14:00', 'Shipped', 119.51, 11.95, 131.46, 'Wire', 'Paid', 47, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400077', 4, '2024-02-05 03:03:00', '2024-02-09 03:03:00', '2024-02-07 03:03:00', 'Pending', 683.77, 68.38, 752.15, 'Cash', 'Unpaid', 41, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400078', 79, '2024-01-30 12:00:00', '2024-02-04 12:00:00', '2024-02-05 12:00:00', 'Delivered', 2543.52, 254.35, 2797.87, 'Cash', 'Paid', 31, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400079', 77, '2024-01-05 23:46:00', '2024-01-06 23:46:00', '2024-01-12 23:46:00', 'Delivered', 399.46, 39.95, 439.41, 'Card', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400080', 98, '2024-02-13 18:45:00', '2024-02-22 18:45:00', '2024-02-19 18:45:00', 'Pending', 4950.51, 495.05, 5445.56, 'Wire', 'Paid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400081', 81, '2024-02-17 01:11:00', '2024-02-21 01:11:00', '2024-02-22 01:11:00', 'Delivered', 3728.16, 372.82, 4100.98, 'Cash', 'Unpaid', 45, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400082', 44, '2024-02-27 15:05:00', '2024-03-04 15:05:00', '2024-02-29 15:05:00', 'Delivered', 124.57, 12.46, 137.03, 'Wire', 'Unpaid', 26, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400083', 49, '2024-01-25 22:29:00', '2024-02-02 22:29:00', '2024-01-26 22:29:00', 'Delivered', 1761.81, 176.18, 1937.99, 'Wire', 'Paid', 17, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400084', 12, '2024-02-05 00:34:00', '2024-02-08 00:34:00', NULL, 'Pending', 436.10, 43.61, 479.71, 'Wire', 'Unpaid', 36, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400085', 93, '2024-01-08 07:27:00', '2024-01-14 07:27:00', '2024-01-12 07:27:00', 'Shipped', 3396.95, 339.69, 3736.64, 'Card', 'Paid', 4, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400086', 37, '2024-01-26 11:58:00', '2024-01-29 11:58:00', '2024-01-30 11:58:00', 'Shipped', 3564.55, 356.46, 3921.01, 'Wire', 'Unpaid', 19, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400087', 41, '2024-01-28 10:32:00', '2024-02-04 10:32:00', '2024-02-03 10:32:00', 'Shipped', 1133.71, 113.37, 1247.08, 'Card', 'Paid', 42, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400088', 77, '2024-02-01 07:28:00', '2024-02-07 07:28:00', NULL, 'Pending', 208.26, 20.83, 229.09, 'Cash', 'Unpaid', 28, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400089', 59, '2024-02-04 00:30:00', '2024-02-07 00:30:00', '2024-02-11 00:30:00', 'Pending', 3412.34, 341.23, 3753.57, 'Cash', 'Paid', 40, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400090', 43, '2024-01-04 15:30:00', '2024-01-08 15:30:00', '2024-01-07 15:30:00', 'Delivered', 2494.81, 249.48, 2744.29, 'Card', 'Unpaid', 22, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400091', 25, '2024-01-18 07:37:00', '2024-01-28 07:37:00', '2024-01-22 07:37:00', 'Shipped', 4104.35, 410.44, 4514.79, 'Wire', 'Paid', 48, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400092', 47, '2024-02-08 09:42:00', '2024-02-14 09:42:00', '2024-02-14 09:42:00', 'Shipped', 3034.02, 303.40, 3337.42, 'Card', 'Unpaid', 40, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400093', 20, '2024-01-05 06:49:00', '2024-01-15 06:49:00', '2024-01-10 06:49:00', 'Pending', 4782.46, 478.25, 5260.71, 'Cash', 'Paid', 10, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400094', 53, '2024-02-02 10:48:00', '2024-02-05 10:48:00', NULL, 'Pending', 4551.75, 455.18, 5006.93, 'Wire', 'Paid', 46, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400095', 81, '2024-02-23 13:15:00', '2024-02-25 13:15:00', '2024-03-01 13:15:00', 'Delivered', 2706.72, 270.67, 2977.39, 'Cash', 'Paid', 27, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400096', 45, '2024-01-03 23:30:00', '2024-01-08 23:30:00', '2024-01-09 23:30:00', 'Shipped', 2478.29, 247.83, 2726.12, 'Card', 'Paid', 23, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400097', 31, '2024-01-31 00:34:00', '2024-02-04 00:34:00', '2024-02-06 00:34:00', 'Pending', 2949.17, 294.92, 3244.09, 'Cash', 'Unpaid', 19, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400098', 85, '2024-02-08 22:10:00', '2024-02-10 22:10:00', '2024-02-14 22:10:00', 'Pending', 1113.88, 111.39, 1225.27, 'Card', 'Unpaid', 21, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400099', 68, '2024-01-19 07:11:00', '2024-01-25 07:11:00', '2024-01-23 07:11:00', 'Pending', 2774.90, 277.49, 3052.39, 'Card', 'Paid', 35, NULL); -INSERT INTO Orders (OrderNumber, CustomerID, OrderDate, RequiredDate, ShippedDate, OrderStatus, SubTotal, TaxAmount, TotalAmount, PaymentMethod, PaymentStatus, EmployeeID, Notes) VALUES ('SO-202400100', 25, '2024-02-08 15:41:00', '2024-02-15 15:41:00', NULL, 'Delivered', 2383.82, 238.38, 2622.20, 'Cash', 'Unpaid', 26, NULL); --- OrderDetails (200 records) -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (17, 69, 1887.53, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (57, 18, 464.59, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 95, 778.97, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (88, 53, 1056.93, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (4, 28, 87.17, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 62, 1238.70, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (81, 90, 24.80, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 90, 17.28, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 82, 169.53, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 6, 1189.14, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 53, 672.63, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (25, 29, 1992.26, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (12, 9, 677.60, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (25, 65, 583.36, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (1, 100, 1286.30, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (34, 73, 992.00, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 7, 783.94, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (29, 6, 184.37, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (48, 65, 1000.09, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (58, 84, 338.56, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (60, 39, 1105.92, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 5, 1733.06, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 97, 596.93, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (47, 43, 1033.80, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (70, 27, 1790.32, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (100, 60, 1470.59, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 86, 533.54, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (77, 47, 214.25, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (97, 76, 454.89, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 28, 1897.98, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 57, 413.09, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 10, 335.91, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (36, 26, 486.58, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 48, 347.28, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (16, 6, 1872.57, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 82, 398.09, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (10, 41, 1106.71, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 8, 1763.40, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (44, 42, 1364.53, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (90, 96, 1398.62, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 68, 1387.49, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 84, 487.72, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 46, 1599.85, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (26, 16, 577.03, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 59, 1383.51, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (64, 64, 419.41, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (97, 97, 159.47, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (42, 37, 1542.70, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (7, 12, 1885.83, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 37, 1876.88, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (96, 100, 972.52, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (17, 64, 619.27, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (58, 15, 1914.19, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 51, 1269.78, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (67, 63, 1118.33, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (26, 9, 1094.65, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (22, 65, 883.95, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (21, 91, 572.56, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 12, 1441.23, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (90, 89, 1299.03, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (92, 1, 510.69, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 3, 1812.75, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (10, 68, 1342.12, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (51, 68, 1766.96, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (77, 39, 572.28, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (4, 91, 870.23, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 64, 1785.73, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (24, 11, 50.29, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 94, 310.15, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (14, 97, 494.04, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 69, 1480.47, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 23, 1108.35, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (5, 42, 1685.96, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (52, 70, 345.13, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (45, 6, 92.16, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (19, 30, 863.11, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 93, 821.54, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (56, 70, 1635.47, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (48, 86, 1540.64, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 68, 833.78, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (45, 25, 37.21, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (96, 72, 1710.10, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (28, 18, 165.88, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 15, 573.05, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (8, 69, 1385.14, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (60, 38, 920.48, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (60, 32, 966.92, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 6, 1834.50, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (48, 73, 975.48, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (94, 15, 102.14, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (91, 73, 737.13, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (29, 98, 1899.24, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 8, 1542.02, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (70, 29, 1227.23, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (89, 97, 1884.64, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 92, 1985.79, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (29, 88, 1657.25, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 32, 1732.36, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (25, 92, 509.37, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (17, 14, 1455.82, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (2, 44, 1274.64, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (89, 36, 1116.30, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 21, 880.00, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 58, 415.09, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (96, 50, 1135.07, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 91, 1202.71, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (24, 46, 1481.28, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (20, 19, 873.27, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (85, 62, 830.23, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (80, 90, 590.23, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 46, 340.20, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (24, 26, 684.65, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (54, 9, 1893.52, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (84, 75, 416.08, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (22, 34, 1379.04, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 5, 1313.51, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 71, 1822.48, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (86, 82, 1458.57, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (59, 24, 574.75, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (88, 74, 1314.29, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (96, 41, 1249.16, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 12, 1858.18, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 78, 1673.35, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 84, 1860.62, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (36, 63, 1508.93, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (21, 55, 760.47, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (3, 27, 563.82, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 79, 1534.48, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (97, 5, 515.89, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (77, 92, 168.88, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (95, 93, 258.53, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (78, 31, 664.85, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 41, 160.07, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (8, 12, 265.88, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (72, 49, 1412.84, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (91, 7, 882.43, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (48, 17, 1567.50, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (80, 11, 68.94, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (64, 17, 717.16, 5, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (91, 80, 729.09, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 63, 1219.61, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (76, 69, 400.38, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 94, 5.54, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (52, 39, 1647.43, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (79, 54, 184.93, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (65, 67, 1487.84, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (82, 50, 119.43, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (35, 41, 1431.30, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (51, 69, 634.93, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 72, 455.28, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 91, 1697.99, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (43, 62, 1768.14, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (1, 38, 1115.62, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (12, 31, 179.27, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (75, 54, 657.65, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (90, 66, 836.13, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (9, 36, 311.86, 2, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 65, 803.33, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (70, 99, 658.20, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (83, 99, 1085.41, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (55, 40, 268.31, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (58, 46, 160.93, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (72, 85, 538.89, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (21, 42, 63.75, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (36, 88, 1661.58, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (32, 74, 482.32, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (68, 10, 1663.31, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (75, 19, 1311.29, 3, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (19, 96, 1620.28, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (59, 3, 1377.07, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (8, 89, 1876.10, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (3, 20, 308.67, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (32, 75, 1988.85, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (38, 83, 1661.68, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (15, 82, 690.82, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (99, 85, 1889.89, 4, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (18, 95, 920.03, 1, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (49, 89, 257.65, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (56, 71, 1849.31, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (54, 36, 1692.15, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (69, 32, 282.17, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (74, 86, 145.18, 1, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 31, 1665.66, 3, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (84, 65, 802.35, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (30, 87, 1776.92, 5, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (45, 57, 109.08, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (75, 36, 1656.90, 1, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (51, 36, 1678.56, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (71, 13, 1187.07, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (100, 33, 1903.42, 3, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (4, 3, 1523.86, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (27, 18, 544.92, 2, 0.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (11, 35, 577.88, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (60, 17, 1015.18, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (78, 34, 1322.92, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (47, 93, 103.91, 4, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (50, 37, 79.79, 5, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (66, 20, 1788.62, 4, 5.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (31, 33, 234.90, 2, 10.00); -INSERT INTO OrderDetails (OrderID, ProductID, UnitPrice, Quantity, Discount) VALUES (93, 11, 927.42, 4, 0.00); From 0cd3263b99a68d8fac282f99db8f600719e5289a Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 8 Nov 2025 22:23:02 +0900 Subject: [PATCH 14/25] Define test query statements for each DB adapter --- src/database/MSSQLAdapter.js | 5 +++++ src/database/MySQLAdapter.js | 5 +++++ src/database/OracleAdapter.js | 5 +++++ src/database/PostgreSQLAdapter.js | 5 +++++ src/database/SQLiteAdapter.js | 5 +++++ src/excel-cli.js | 6 +++--- 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/database/MSSQLAdapter.js b/src/database/MSSQLAdapter.js index 6d6c1d6..10becdd 100644 --- a/src/database/MSSQLAdapter.js +++ b/src/database/MSSQLAdapter.js @@ -181,6 +181,11 @@ class MSSQLAdapter { getType() { return this.dbType; } + + /** 연결 테스트용 쿼리 */ + getTestQuery() { + return 'SELECT 1 as test'; + } } module.exports = MSSQLAdapter; diff --git a/src/database/MySQLAdapter.js b/src/database/MySQLAdapter.js index 67e1ee5..9371d69 100644 --- a/src/database/MySQLAdapter.js +++ b/src/database/MySQLAdapter.js @@ -212,6 +212,11 @@ class MySQLAdapter { getType() { return this.dbType; } + + /** 연결 테스트용 쿼리 */ + getTestQuery() { + return 'SELECT 1 as test'; + } } module.exports = MySQLAdapter; diff --git a/src/database/OracleAdapter.js b/src/database/OracleAdapter.js index 8f5f5e5..e1e9182 100644 --- a/src/database/OracleAdapter.js +++ b/src/database/OracleAdapter.js @@ -181,6 +181,11 @@ class OracleAdapter { /** DB 타입 */ getType() { return this.dbType; } + + /** 연결 테스트용 쿼리 */ + getTestQuery() { + return 'SELECT 1 FROM dual'; + } } module.exports = OracleAdapter; diff --git a/src/database/PostgreSQLAdapter.js b/src/database/PostgreSQLAdapter.js index bf59176..d354317 100644 --- a/src/database/PostgreSQLAdapter.js +++ b/src/database/PostgreSQLAdapter.js @@ -218,6 +218,11 @@ class PostgreSQLAdapter { getType() { return this.dbType; } + + /** 연결 테스트용 쿼리 */ + getTestQuery() { + return 'SELECT 1'; + } } module.exports = PostgreSQLAdapter; diff --git a/src/database/SQLiteAdapter.js b/src/database/SQLiteAdapter.js index 453e2f3..c241f90 100644 --- a/src/database/SQLiteAdapter.js +++ b/src/database/SQLiteAdapter.js @@ -227,6 +227,11 @@ class SQLiteAdapter { getType() { return this.dbType; } + + /** 연결 테스트용 쿼리 */ + getTestQuery() { + return 'SELECT 1'; + } } module.exports = SQLiteAdapter; diff --git a/src/excel-cli.js b/src/excel-cli.js index 471effc..5d597b0 100644 --- a/src/excel-cli.js +++ b/src/excel-cli.js @@ -350,7 +350,6 @@ function loadDatabaseConfig(configPath) { } } -// 데이터베이스 연결 테스트 async function testDatabaseConnection(dbKey, dbConfig) { let connection = null; let adapter = null; @@ -364,8 +363,9 @@ async function testDatabaseConnection(dbKey, dbConfig) { adapter = DatabaseFactory.createAdapter(dbType, dbConfig, LANGUAGE); connection = await adapter.createConnectionPool(dbConfig, dbKey); - // 연결 테스트 쿼리 실행 - await adapter.executeQuery(connection, 'SELECT 1 as test'); + // 연결 테스트 쿼리 실행 (각 Adapter에 정의된 테스트 쿼리 사용) + const testSql = (typeof adapter.getTestQuery === 'function') ? adapter.getTestQuery() : 'SELECT 1 as test'; + await adapter.executeQuery(connection, testSql); console.log(msg.dbConnectionSuccess.replace('{dbKey}', dbKey)); return { success: true, message: msg.dbConnectionSuccess.replace('{dbKey}', '') }; From 349b3da0640e9983a587f28cf70cafb8ba53fc1b Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 8 Nov 2025 22:24:12 +0900 Subject: [PATCH 15/25] Update sample queries and db schema creation script --- config/dbinfo.json | 4 +-- queries/queries-sample-orders.xml | 34 +++++++------------ resources/create_sample_tables_mysql.sql | 4 +++ resources/create_sample_tables_postgresql.sql | 4 +++ 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/config/dbinfo.json b/config/dbinfo.json index 40094fd..a0d17f4 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -59,9 +59,9 @@ "postgresDB": { "type": "postgresql", "user": "postgres", - "password": "password", + "password": "1111", "server": "localhost", - "database": "mydb", + "database": "postgres", "port": 5432, "options": { "max": 10, diff --git a/queries/queries-sample-orders.xml b/queries/queries-sample-orders.xml index 0695307..57cf22c 100644 --- a/queries/queries-sample-orders.xml +++ b/queries/queries-sample-orders.xml @@ -1,5 +1,5 @@ - + @@ -9,47 +9,47 @@ 2024-01-01 2024-06-30 ["Seoul", "Busan"] - ["ACTIVE", "PENDING", "COMPLETED"] + ["Pending", "Shipped", "Delivered"] [1, 2, 3, 5] 1000 - + = '${startDate}' AND OrderDate <= '${endDate}' ORDER BY OrderDate DESC ]]> - + - + = '${startDate}' AND o.OrderDate <= '${endDate}' ORDER BY o.OrderDate DESC ]]> - + - + - - - \ No newline at end of file diff --git a/resources/create_sample_tables_mysql.sql b/resources/create_sample_tables_mysql.sql index e485062..e3e4471 100644 --- a/resources/create_sample_tables_mysql.sql +++ b/resources/create_sample_tables_mysql.sql @@ -56,11 +56,15 @@ CREATE TABLE Orders ( RequiredDate DATETIME NULL, ShippedDate DATETIME NULL, OrderStatus VARCHAR(20) DEFAULT 'Pending', + SubTotal DECIMAL(15,2) DEFAULT 0, TotalAmount DECIMAL(15,2) DEFAULT 0, DiscountAmount DECIMAL(15,2) DEFAULT 0, TaxAmount DECIMAL(15,2) DEFAULT 0, NetAmount DECIMAL(15,2) DEFAULT 0, ShippingAddress VARCHAR(200) NULL, + PaymentMethod VARCHAR(30) NULL, + PaymentStatus VARCHAR(20) DEFAULT 'Unpaid', + EmployeeID INT NULL, Notes TEXT NULL, CreatedDate DATETIME DEFAULT CURRENT_TIMESTAMP, LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, diff --git a/resources/create_sample_tables_postgresql.sql b/resources/create_sample_tables_postgresql.sql index 2de202d..de4ad7d 100644 --- a/resources/create_sample_tables_postgresql.sql +++ b/resources/create_sample_tables_postgresql.sql @@ -71,11 +71,15 @@ CREATE TABLE Orders ( RequiredDate TIMESTAMP NULL, ShippedDate TIMESTAMP NULL, OrderStatus VARCHAR(20) DEFAULT 'Pending', + SubTotal DECIMAL(15,2) DEFAULT 0, TotalAmount DECIMAL(15,2) DEFAULT 0, DiscountAmount DECIMAL(15,2) DEFAULT 0, TaxAmount DECIMAL(15,2) DEFAULT 0, NetAmount DECIMAL(15,2) DEFAULT 0, ShippingAddress VARCHAR(200) NULL, + PaymentMethod VARCHAR(30) NULL, + PaymentStatus VARCHAR(20) DEFAULT 'Unpaid', + EmployeeID INTEGER NULL, Notes TEXT NULL, CreatedDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, LastUpdated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, From 7b9d2eebb53d3e920beb8c89f7c4bfdae4c1fd63 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 8 Nov 2025 22:40:44 +0900 Subject: [PATCH 16/25] Update document --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ CHANGELOG_KR.md | 35 +++++++++++++++++++++++++++++++++++ README.md | 10 ++++++++++ README_KR.md | 10 ++++++++++ USER_MANUAL.md | 10 ++++++++++ USER_MANUAL_KR.md | 10 ++++++++++ 6 files changed, 110 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36e3d0d..0b56dc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # SQL2Excel Version History +## v1.3.4 - DB Adapter Test Query & Schema Alignment (2025-11-08) + +### ✨ New/Changed +- Adapter-level connection test SQL + - Added `getTestQuery()` to all DB adapters + - MSSQL: `SELECT 1 as test` + - MySQL/MariaDB: `SELECT 1 as test` + - PostgreSQL: `SELECT 1` + - SQLite: `SELECT 1` + - Oracle: `SELECT 1 FROM dual` + - `excel-cli.js` uses `adapter.getTestQuery()` for connection validation + +- Sample schema alignment for cross-DB consistency (Orders) + - PostgreSQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` + - MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` + - Purpose: match sample data columns and improve parity with MSSQL schema + +### 🐛 Fixes +- Oracle connection validation fixed during `list-dbs`/validation flows + - Replaced hardcoded `SELECT 1 as test` with adapter-provided query +- `excel-cli.js`: fixed broken `catch` in `loadDatabaseConfig()` and improved error message (`configFileLoadFailed`) + +### 🔧 Code Changes +- `src/database/OracleAdapter.js`: add `getTestQuery()` +- `src/database/MSSQLAdapter.js`: add `getTestQuery()` +- `src/database/MySQLAdapter.js`: add `getTestQuery()` +- `src/database/PostgreSQLAdapter.js`: add `getTestQuery()` +- `src/database/SQLiteAdapter.js`: add `getTestQuery()` +- `src/excel-cli.js`: use `adapter.getTestQuery()`; fix `loadDatabaseConfig()` catch block +- `resources/create_sample_tables_postgresql.sql`: add Orders columns (`SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID`) +- `resources/create_sample_tables_mysql.sql`: add Orders columns (`SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID`) + +### 📝 Notes +- These changes ensure sample data (PostgreSQL) loads cleanly across DBs when schemas are applied accordingly. + ## v1.3.3 - Docs Sync & Version Bump (2025-10-31) ### ✨ New/Changed diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index d4ff9c9..759a3c0 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -1,5 +1,40 @@ # SQL2Excel 버전 히스토리 +## v1.3.4 - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) + +### ✨ 변경 사항 +- 어댑터 단위 연결 테스트 SQL 도입 + - 모든 DB 어댑터에 `getTestQuery()` 추가 + - MSSQL: `SELECT 1 as test` + - MySQL/MariaDB: `SELECT 1 as test` + - PostgreSQL: `SELECT 1` + - SQLite: `SELECT 1` + - Oracle: `SELECT 1 FROM dual` + - `excel-cli.js`는 연결 검증 시 어댑터의 `getTestQuery()`를 사용 + +- 샘플 스키마 정합성(Orders) + - PostgreSQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 + - MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 + - 목적: 샘플 데이터 컬럼과 일치 및 MSSQL 스키마와의 정합성 향상 + +### 🐛 버그 수정 +- Oracle 연결 검증 오류 수정 (`list-dbs`/검증 플로우) + - 하드코딩된 `SELECT 1 as test` → 어댑터 제공 테스트 쿼리로 대체 +- `excel-cli.js`: `loadDatabaseConfig()`의 깨진 `catch` 블록 수정 및 오류 메시지 개선(`configFileLoadFailed`) + +### 🔧 코드 변경 +- `src/database/OracleAdapter.js`: `getTestQuery()` 추가 +- `src/database/MSSQLAdapter.js`: `getTestQuery()` 추가 +- `src/database/MySQLAdapter.js`: `getTestQuery()` 추가 +- `src/database/PostgreSQLAdapter.js`: `getTestQuery()` 추가 +- `src/database/SQLiteAdapter.js`: `getTestQuery()` 추가 +- `src/excel-cli.js`: 어댑터의 테스트 쿼리 사용; `loadDatabaseConfig()` catch 블록 수정 +- `resources/create_sample_tables_postgresql.sql`: Orders 컬럼 추가 (`SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID`) +- `resources/create_sample_tables_mysql.sql`: Orders 컬럼 추가 (`SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID`) + +### 📝 비고 +- 본 변경으로 샘플 데이터(PostgreSQL)가 각 DB 스키마 적용 시 원활히 적재되도록 정합성이 개선되었습니다. + ## v1.3.3 - 문서 동기화 및 버전 올림 (2025-10-31) ### ✨ 변경 사항 diff --git a/README.md b/README.md index 65acb2c..534e653 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ A Node.js-based tool for generating Excel files from SQL query results. +## v1.3.4 Highlights + +- Adapter-level DB connection test queries + - Added `getTestQuery()` to all DB adapters + - MSSQL: `SELECT 1 as test`, MySQL/MariaDB: `SELECT 1 as test`, PostgreSQL: `SELECT 1`, SQLite: `SELECT 1`, Oracle: `SELECT 1 FROM dual` + - `excel-cli.js` now uses the adapter’s test query for connection validation (fixes Oracle validation) +- Sample schema alignment (Orders) + - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` + - Aligns with sample data and improves parity with MSSQL schema + ## v1.3.3 Highlights - Documentation synchronization (KR/EN) and minor updates diff --git a/README_KR.md b/README_KR.md index 0671f7f..981bc28 100644 --- a/README_KR.md +++ b/README_KR.md @@ -2,6 +2,16 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니다. +## v1.3.4 하이라이트 + +- 어댑터별 DB 연결 테스트 쿼리 도입 + - 모든 DB 어댑터에 `getTestQuery()` 추가 + - MSSQL/MySQL/MariaDB: `SELECT 1 as test`, PostgreSQL/SQLite: `SELECT 1`, Oracle: `SELECT 1 FROM dual` + - `excel-cli.js`가 어댑터의 테스트 쿼리를 사용하여 연결 검증 수행 (Oracle 검증 이슈 해결) +- 샘플 스키마 정합성(Orders) + - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 + - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 + ## v1.3.3 하이라이트 - 문서 동기화(KR/EN) 및 소규모 정리 diff --git a/USER_MANUAL.md b/USER_MANUAL.md index d4a6ad7..dabc3f2 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -19,6 +19,16 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL query results with advanced styling, template support, and standalone executable distribution. +### What's New (v1.3.4) + +- Adapter-level DB connection test queries + - Added `getTestQuery()` to all DB adapters + - MSSQL: `SELECT 1 as test`, MySQL/MariaDB: `SELECT 1 as test`, PostgreSQL: `SELECT 1`, SQLite: `SELECT 1`, Oracle: `SELECT 1 FROM dual` + - `excel-cli.js` now uses the adapter’s test query for connection validation (fixes Oracle validation) +- Sample schema alignment (Orders) + - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` + - Aligns with sample data and improves parity with MSSQL schema + ### What's New (v1.3.3) - Added `exceptColumns` sheet option (XML/JSON) to exclude specific columns from outputs diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index 43bc8d1..e8ddffe 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -19,6 +19,16 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 기능을 갖춘 SQL 쿼리 결과로 엑셀 파일을 생성하는 강력한 Node.js 기반 도구입니다. +### v1.3.4 주요 변경 + +- 어댑터별 DB 연결 테스트 쿼리 도입 + - 모든 DB 어댑터에 `getTestQuery()` 추가 + - MSSQL: `SELECT 1 as test`, MySQL/MariaDB: `SELECT 1 as test`, PostgreSQL: `SELECT 1`, SQLite: `SELECT 1`, Oracle: `SELECT 1 FROM dual` + - `excel-cli.js`가 어댑터의 테스트 쿼리를 사용하여 연결 검증 수행 (Oracle 검증 이슈 해결) +- 샘플 스키마 정합성(Orders) + - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 + - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 + ### v1.3.3 주요 변경 - 시트에서 특정 컬럼 제외를 위한 `exceptColumns` 속성 추가 (XML/JSON) From 5203419a36c372c9a65e33672e402abae6f1b9a6 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 14:46:25 +0900 Subject: [PATCH 17/25] Application of a two-point version system --- CHANGELOG.md | 14 +++++++------- CHANGELOG_KR.md | 12 ++++++------ README.md | 10 +++++----- README_KR.md | 10 +++++----- USER_MANUAL.md | 6 +++--- USER_MANUAL_KR.md | 6 +++--- package.json | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b56dc8..2fd3344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # SQL2Excel Version History -## v1.3.4 - DB Adapter Test Query & Schema Alignment (2025-11-08) +## v2.1.4-beta(v1.3.4) - DB Adapter Test Query & Schema Alignment (2025-11-08) ### ✨ New/Changed - Adapter-level connection test SQL @@ -35,7 +35,7 @@ ### 📝 Notes - These changes ensure sample data (PostgreSQL) loads cleanly across DBs when schemas are applied accordingly. -## v1.3.3 - Docs Sync & Version Bump (2025-10-31) +## v2.1.4-beta(v1.3.3) - Docs Sync & Version Bump (2025-10-31) ### ✨ New/Changed - Added `exceptColumns` attribute to exclude specific columns from sheet output @@ -53,7 +53,7 @@ ### 📝 Documentation - README/README_KR, USER_MANUAL/USER_MANUAL_KR, CHANGELOG/CHANGELOG_KR updated accordingly -## v1.3.2 - CSV/TXT Formatting & Directory Naming (2025-10-31) +## v2.1.2-beta(v1.3.2) - CSV/TXT Formatting & Directory Naming (2025-10-31) ### ✨ New/Changed - Per-sheet export directory naming simplified @@ -78,7 +78,7 @@ - USER_MANUAL/USER_MANUAL_KR: Updated per-sheet export section to reflect new directory naming and formatting rules - CHANGELOG/CHANGELOG_KR: Added v1.3.2 entry -## v1.3.1 - Filename Variables and DATE Fixes (2025-10-30) +## v2.1.1-beta(v1.3.1) - Filename Variables and DATE Fixes (2025-10-30) ### ✨ New/Changed - Output filename variable enhancements @@ -101,7 +101,7 @@ - USER_MANUAL/USER_MANUAL_KR: Documented filename variables (`DB_NAME`, DATE), lowercase tokens, and local-time behavior - CHANGELOG/CHANGELOG_KR: Added v1.3.1 entry -## v1.3.0 - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) +## v2.1.0-beta(v1.3.0) - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) ### ✨ New/Changed - Export routing based on output extension @@ -128,7 +128,7 @@ - USER_MANUAL/USER_MANUAL_KR: Added section describing routing, directory/filename rules, and defaults - CHANGELOG/CHANGELOG_KR: Added v1.3.0 entry -## v1.2.11 - TOC Original Name & Sheet Name Length Warning (2025-10-29) +## v2.0.11-beta(v1.2.11) - TOC Original Name & Sheet Name Length Warning (2025-10-29) ### ✨ New/Changed - Sheet name length > 31 characters is now treated as a warning during validation (no failure) @@ -146,7 +146,7 @@ - README/README_KR: Updated highlights to v1.2.11, described changes - CHANGELOG: Added v1.2.11 entry -## v1.2.10 - Non-interactive CLI & Docs (2025-10-29) +## v2.0.10-beta(v1.2.10) - Non-interactive CLI & Docs (2025-10-29) ### ✨ New Features diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index 759a3c0..d7fe3c4 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -1,6 +1,6 @@ # SQL2Excel 버전 히스토리 -## v1.3.4 - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) +## v2.1.4-beta(v1.3.4) - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) ### ✨ 변경 사항 - 어댑터 단위 연결 테스트 SQL 도입 @@ -35,7 +35,7 @@ ### 📝 비고 - 본 변경으로 샘플 데이터(PostgreSQL)가 각 DB 스키마 적용 시 원활히 적재되도록 정합성이 개선되었습니다. -## v1.3.3 - 문서 동기화 및 버전 올림 (2025-10-31) +## v2.1.3-beta(v1.3.3) - 문서 동기화 및 버전 올림 (2025-10-31) ### ✨ 변경 사항 - 시트에서 특정 컬럼을 결과에서 제외하는 `exceptColumns` 속성 추가 @@ -58,7 +58,7 @@ - KR/EN 문서(README, USER_MANUAL, CHANGELOG) 동기화 - 패키지 버전을 1.3.3으로 업데이트 -## v1.3.1 - 파일명 변수 및 DATE 개선 (2025-10-30) +## v2.1.1-beta(v1.3.1) - 파일명 변수 및 DATE 개선 (2025-10-30) ### ✨ 변경 사항 - 출력 파일명 변수 기능 강화 @@ -81,7 +81,7 @@ - USER_MANUAL/USER_MANUAL_KR: 파일명 변수(`DB_NAME`, DATE), 소문자 토큰, 로컬 시간 동작 설명 추가 - CHANGELOG/CHANGELOG_KR: v1.3.1 항목 추가 -## v1.3.0 - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) +## v2.1.0-beta(v1.3.0) - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) ### ✨ 변경 사항 - 출력 확장자에 따른 라우팅 @@ -108,7 +108,7 @@ - USER_MANUAL/USER_MANUAL_KR: 라우팅, 디렉토리/파일명 규칙, 기본값 섹션 추가 - CHANGELOG/CHANGELOG_KR: v1.3.0 항목 추가 -## v1.2.11 - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) +## v2.0.11-beta(v1.2.11) - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) ### ✨ 변경 사항 - 시트명 길이 31자 초과 시 이제 검증에서 오류가 아닌 경고로 처리합니다. @@ -126,7 +126,7 @@ - README/README_KR: v1.2.11 하이라이트 및 변경점 반영 - CHANGELOG/CHANGELOG_KR: v1.2.11 항목 추가 -## v1.2.10 - 비대화식 CLI 및 문서 업데이트 (2025-10-29) +## v2.0.10-beta(v1.2.10) - 비대화식 CLI 및 문서 업데이트 (2025-10-29) ### ✨ 새로운 기능 diff --git a/README.md b/README.md index 534e653..15454a4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Node.js-based tool for generating Excel files from SQL query results. -## v1.3.4 Highlights +## v2.1.4-beta(v1.3.4) Highlights - Adapter-level DB connection test queries - Added `getTestQuery()` to all DB adapters @@ -12,7 +12,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` - Aligns with sample data and improves parity with MSSQL schema -## v1.3.3 Highlights +## v2.1.3-beta(v1.3.3) Highlights - Documentation synchronization (KR/EN) and minor updates - Package version updated to 1.3.3 @@ -42,7 +42,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - 🔧 **Input Validation**: Automatic whitespace trimming for file path inputs - 🗂️ **Filename Variables**: Use `${DATE:...}`, `${DATE.TZ:...}`, and `${DB_NAME}` in `excel.output` (also supports custom `$(DB_NAME}`) -## v1.3.2 Highlights +## v2.1.2-beta(v1.3.2) Highlights - Per-sheet export directory naming simplified - Directory is now `` (extension suffix removed) @@ -54,7 +54,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Record separators remain CRLF; headers included - Date values are serialized as `yyyy-MM-dd HH:mm:ss` (24-hour) in CSV/TXT and SQL literals -## v1.3.1 Highlights +## v2.1.1-beta(v1.3.1) Highlights - Filename variables in output path - Support `${DB_NAME}` (current DB key), custom syntax `$(DB_NAME}` normalized automatically @@ -62,7 +62,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Lowercase date tokens supported: `yyyy, yy, dd, d, hh, h, sss` - Removed auto `_yyyymmddhhmmss` suffix; control naming via DATE variables -## v1.3.0 Highlights +## v2.1.0-beta(v1.3.0) Highlights - **Per-sheet export routing by extension** - `.xlsx` / `.xls` → Generate a single Excel workbook (existing behavior) diff --git a/README_KR.md b/README_KR.md index 981bc28..6ffaf85 100644 --- a/README_KR.md +++ b/README_KR.md @@ -2,7 +2,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니다. -## v1.3.4 하이라이트 +## v2.1.4-beta(v1.3.4) 하이라이트 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -12,7 +12,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -## v1.3.3 하이라이트 +## v2.1.3-beta(v1.3.3) 하이라이트 - 문서 동기화(KR/EN) 및 소규모 정리 - 패키지 버전을 1.3.3으로 업데이트 @@ -42,7 +42,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 🔧 **입력 유효성 검증**: 파일 경로 입력에 대한 자동 공백 제거 - 🗂️ **파일명 변수**: `excel.output`에서 `${DATE:...}`, `${DATE.TZ:...}`, `${DB_NAME}` 사용 가능 (커스텀 `$(DB_NAME}`도 지원) -## v1.3.2 하이라이트 +## v2.1.2-beta(v1.3.2) 하이라이트 - 시트별 내보내기 디렉토리 명명 단순화 - 디렉토리는 이제 `<출력파일베이스>` (확장자 접미사 제거) @@ -54,7 +54,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 레코드 구분 개행은 CRLF 유지, 헤더 포함 - 날짜 값은 CSV/TXT 및 SQL 리터럴에서 `yyyy-MM-dd HH:mm:ss`(24시간) 형식으로 직렬화 -## v1.3.1 하이라이트 +## v2.1.1-beta(v1.3.1) 하이라이트 - 출력 경로에서 파일명 변수 지원 강화 - `${DB_NAME}` 지원 (현재 기본 DB 키). 커스텀 문법 `$(DB_NAME}`는 자동으로 `${DB_NAME}`로 정규화 @@ -62,7 +62,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 소문자 날짜 토큰 지원: `yyyy, yy, dd, d, hh, h, sss` - 자동 `_yyyymmddhhmmss` 접미사 제거 → DATE 변수로 직접 제어 -## v1.3.0 하이라이트 +## v2.1.0-beta(v1.3.0) 하이라이트 - **확장자 기반 시트별 내보내기 라우팅** - `.xlsx` / `.xls` → 단일 엑셀 통합문서 생성 (기존 동작) diff --git a/USER_MANUAL.md b/USER_MANUAL.md index dabc3f2..cabcde9 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -19,7 +19,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL query results with advanced styling, template support, and standalone executable distribution. -### What's New (v1.3.4) +### What's New (v2.1.4-beta, v1.3.4) - Adapter-level DB connection test queries - Added `getTestQuery()` to all DB adapters @@ -29,7 +29,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` - Aligns with sample data and improves parity with MSSQL schema -### What's New (v1.3.3) +### What's New (v2.1.3-beta, v1.3.3) - Added `exceptColumns` sheet option (XML/JSON) to exclude specific columns from outputs - Documentation synchronization across KR/EN @@ -59,7 +59,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 📋 **SQL Query Formatting**: Preserve original SQL formatting with line breaks in Table of Contents - 🔧 **Input Validation**: Automatic whitespace trimming for file path inputs -### What's New (v1.3.2) +### What's New (v2.1.2-beta, v1.3.2) - Per-sheet export routing by extension - `.xlsx` / `.xls` → Generate a single Excel workbook (existing behavior) diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index e8ddffe..a5a0d91 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -19,7 +19,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 기능을 갖춘 SQL 쿼리 결과로 엑셀 파일을 생성하는 강력한 Node.js 기반 도구입니다. -### v1.3.4 주요 변경 +### v2.1.4-beta(v1.3.4) 주요 변경 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -29,7 +29,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -### v1.3.3 주요 변경 +### v2.1.3-beta(v1.3.3) 주요 변경 - 시트에서 특정 컬럼 제외를 위한 `exceptColumns` 속성 추가 (XML/JSON) @@ -57,7 +57,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 📋 **SQL 쿼리 포맷팅**: 목차에서 줄바꿈을 포함한 원본 SQL 포맷 유지 - 🔧 **입력 유효성 검증**: 파일 경로 입력에 대한 자동 공백 제거 -### What's New (v1.3.2) +### v2.1.2-beta(v1.3.2) What's New - 확장자 기반 시트별 내보내기 라우팅(유지) - `.xlsx` / `.xls` → 단일 엑셀 통합문서 생성 (기존 동작) diff --git a/package.json b/package.json index 11954ea..469e9d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "1.3.3", + "version": "2.1.4-beta", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { From 6e9a470ca75eaf70e90957557396af38dac87b56 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 18:28:24 +0900 Subject: [PATCH 18/25] Improved functionality to allow db attributes in dynamic variable definitions. --- src/index.js | 5 +---- src/query-parser.js | 6 +++--- src/variable-processor.js | 20 +++++++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/index.js b/src/index.js index 4ed10b7..1acee95 100644 --- a/src/index.js +++ b/src/index.js @@ -247,15 +247,12 @@ async function main() { return await adapter.createConnectionPool(configObj[dbKey], dbKey); } - // 기본 DB 어댑터 가져오기 - const defaultAdapter = dbAdapters[defaultDbKey]; - // 기본 DB 연결 const defaultPool = await getDbPool(defaultDbKey); // 동적 변수 처리 (DB 연결 후, 시트 처리 전) if (dynamicVars && dynamicVars.length > 0) { - await variableProcessor.processDynamicVariables(dynamicVars, defaultAdapter, defaultDbKey, mergedVars, configObj); + await variableProcessor.processDynamicVariables(dynamicVars, dbAdapters, defaultDbKey, mergedVars, configObj); } // 엑셀 파일 경로 결정 (CLI > excel > 쿼리파일 > 기본값) diff --git a/src/query-parser.js b/src/query-parser.js index 444bc7a..8cf9374 100644 --- a/src/query-parser.js +++ b/src/query-parser.js @@ -135,8 +135,8 @@ class QueryParser { const allowedAttributes = { excel: ['db', 'output', 'maxRows', 'style', 'aggregateInfoTemplate'], var: ['name'], - dynamicVar: ['name', 'description', 'type', 'database'], - queryDef: ['id', 'description'], + dynamicVar: ['name', 'description', 'type', 'database', 'db'], + queryDef: ['id', 'description', 'db'], // exceptColumns 속성 사용 (대소문자 구분 없이 허용), 하위호환: except_columns도 파싱에서 지원 sheet: ['name', 'use', 'queryRef', 'aggregateColumn', 'aggregateInfoTemplate', 'maxRows', 'db', 'style', 'exceptColumns'], param: ['name'] @@ -339,7 +339,7 @@ class QueryParser { const query = dv._.toString().trim(); const type = dv.$.type || 'column_identified'; const description = dv.$.description || ''; - const database = dv.$.database || ''; + const database = dv.$.database || dv.$.db || ''; dynamicVars.push({ name: dv.$.name, diff --git a/src/variable-processor.js b/src/variable-processor.js index fa00bd7..a75c207 100644 --- a/src/variable-processor.js +++ b/src/variable-processor.js @@ -124,12 +124,12 @@ class VariableProcessor { /** * 동적 변수 처리 * @param {Array} dynamicVars - 동적 변수 정의 배열 - * @param {Object} dbAdapter - 데이터베이스 어댑터 인스턴스 - * @param {string} dbKey - 데이터베이스 키 + * @param {Object} dbAdapters - 데이터베이스 어댑터 맵 (dbKey -> adapter) + * @param {string} defaultDbKey - 기본 데이터베이스 키 * @param {Object} globalVars - 전역 변수 * @param {Object} configObj - 데이터베이스 설정 객체 */ - async processDynamicVariables(dynamicVars, dbAdapter, dbKey, globalVars, configObj) { + async processDynamicVariables(dynamicVars, dbAdapters, defaultDbKey, globalVars, configObj) { // 동적 변수 초기화 this.dynamicVariables = {}; @@ -140,17 +140,23 @@ class VariableProcessor { if (dynamicVar.name && dynamicVar.query) { try { console.log(`${this.msg.dynamicVarProcessing} ${dynamicVar.name} (${dynamicVar.description || this.msg.noDesc})`); - + // 쿼리에서 변수 치환 (기존 변수들로) const processedQuery = this.substituteVars(dynamicVar.query, globalVars); // 동적 변수에 지정된 데이터베이스 사용 (있으면), 없으면 기본값 사용 - const targetDbKey = dynamicVar.database || dbKey; + const targetDbKey = dynamicVar.database || defaultDbKey; console.log(`${this.msg.database} ${targetDbKey} (${dynamicVar.database ? this.msg.dynamicVarSpecified : this.msg.default})`); + // 대상 DB에 맞는 어댑터 선택 + const adapter = dbAdapters[targetDbKey] || dbAdapters[defaultDbKey]; + if (!adapter) { + throw new Error(`DB adapter not found for key: ${targetDbKey}`); + } + // DB에서 데이터 조회 - const pool = await dbAdapter.createConnectionPool(configObj[targetDbKey], targetDbKey); - const result = await dbAdapter.executeQuery(pool, processedQuery); + const pool = await adapter.createConnectionPool(configObj[targetDbKey], targetDbKey); + const result = await adapter.executeQuery(pool, processedQuery); if (result.recordset && result.recordset.length > 0) { const data = result.recordset; From f1a2de79a19592abed71a2b7f3e95026d965e2c6 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 18:29:26 +0900 Subject: [PATCH 19/25] Modify the task query statement --- config/dbinfo.json | 14 +++--- queries/queries-sample-orders.xml | 2 +- queries/queries-with-dynamic-variables.xml | 53 ++++++++++------------ 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/config/dbinfo.json b/config/dbinfo.json index a0d17f4..4ae2e6d 100644 --- a/config/dbinfo.json +++ b/config/dbinfo.json @@ -33,10 +33,10 @@ "user": "sahara", "password": "1111", "server": "localhost", - "database": "mydb", + "database": "sampledb", "port": 3306, "options": { - "connectionTimeout": 30000 + "connectionTimeout": 3000 } }, "sourceDB": { @@ -52,8 +52,8 @@ "encrypt": true, "trustServerCertificate": true, "enableArithAbort": true, - "requestTimeout": 300000, - "connectionTimeout": 30000 + "requestTimeout": 3000, + "connectionTimeout": 3000 } }, "postgresDB": { @@ -65,8 +65,8 @@ "port": 5432, "options": { "max": 10, - "idleTimeoutMillis": 30000, - "connectionTimeout": 30000 + "idleTimeoutMillis": 3000, + "connectionTimeout": 3000 } }, "sqliteDB": { @@ -87,7 +87,7 @@ "poolMin": 0, "poolMax": 4, "poolIncrement": 1, - "queueTimeout": 30000, + "queueTimeout": 3000, "stmtCacheSize": 30 } } diff --git a/queries/queries-sample-orders.xml b/queries/queries-sample-orders.xml index 57cf22c..1ab8229 100644 --- a/queries/queries-sample-orders.xml +++ b/queries/queries-sample-orders.xml @@ -49,7 +49,7 @@ ORDER BY o.OrderDate DESC ]]> - + - + @@ -19,7 +19,7 @@ - + - - + + - + = '${startDate}' - AND OrderDate <= '${endDate}' - AND OrderDate >= DATEADD(day, -30, '${CURRENT_DATE}') - ORDER BY OrderDate DESC + FROM Orders ]]> @@ -70,7 +65,7 @@ c.City as City, c.Region as Region, c.CustomerType as CustomerType - FROM SampleDB.dbo.Customers c + FROM Customers c WHERE c.Region IN (${regionList}) ORDER BY c.CustomerID ]]> @@ -79,58 +74,58 @@ - + ["서울", "부산"] - + - + - + = '${startDate}' + AND o.OrderID IN (${activeOrders.OrderID}) + AND o.OrderDate >= '${startDate}' AND o.OrderDate <= '${endDate}' GROUP BY c.CustomerName, c.Region ORDER BY TotalOrderAmount DESC From aef2c3e5e55c4201a3d838890058c14b18ab8faa Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 18:37:14 +0900 Subject: [PATCH 20/25] Update document for v2.1.5 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ CHANGELOG_KR.md | 24 ++++++++++++++++++++++++ README.md | 16 ++++++++++++++-- README_KR.md | 16 ++++++++++++++-- USER_MANUAL.md | 20 ++++++++++++++++---- USER_MANUAL_KR.md | 20 ++++++++++++++++---- package.json | 2 +- 7 files changed, 109 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd3344..096f883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # SQL2Excel Version History +## v2.1.5-beta(v1.3.5) - DynamicVar DB Routing & XML Validation Update (2025-11-15) + +### ✨ New/Changed +- Dynamic variable DB routing + - XML `dynamicVar` supports `db` (alias of `database`) attribute + - Each dynamic variable is executed using the adapter for its specified DB key + - Fallback to default DB when not specified +- XML validation update + - `queryDef` now allows `db` attribute during structure validation (for documentation/future use). Execution DB remains sheet-level `db` or global default + +### 🔧 Code Changes +- `src/query-parser.js` + - Allow `db` attribute on `dynamicVar`; parse `database || db` + - Allow `db` attribute on `queryDef` in validation +- `src/variable-processor.js` + - Execute dynamic variables on their own DB adapters (`dbAdapters[targetDbKey]`) +- `src/index.js` + - Pass `dbAdapters` and `defaultDbKey` to dynamic variable processor + +### 📝 Documentation +- README/README_KR: Added v2.1.5 highlights, dynamicVar `db`/`database` usage notes and examples +- USER_MANUAL/USER_MANUAL_KR: Documented dynamicVar attributes and per-variable DB routing +- CHANGELOG/CHANGELOG_KR: Added v2.1.5 entries + ## v2.1.4-beta(v1.3.4) - DB Adapter Test Query & Schema Alignment (2025-11-08) ### ✨ New/Changed diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index d7fe3c4..ec39186 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -1,5 +1,29 @@ # SQL2Excel 버전 히스토리 +## v2.1.5-beta(v1.3.5) - 동적 변수 DB 라우팅 & XML 검증 업데이트 (2025-11-15) + +### ✨ 변경 사항 +- 동적 변수 DB 라우팅 + - XML `dynamicVar`에서 `db` 속성 지원 (`database`의 별칭) + - 각 동적 변수는 지정된 DB 키의 어댑터로 실행 + - 미지정 시 전역 기본 DB로 폴백 +- XML 검증 업데이트 + - XML 구조 검증에서 `queryDef`의 `db` 속성을 허용 (문서/향후 확장용). 실제 실행 DB는 시트의 `db` 또는 전역 기본 DB가 적용됨 + +### 🔧 코드 변경 +- `src/query-parser.js` + - `dynamicVar`에 `db` 속성 허용; 파싱 시 `database || db` 처리 + - XML 검증에서 `queryDef`의 `db` 속성 허용 +- `src/variable-processor.js` + - 동적 변수를 해당 DB 어댑터로 실행 (`dbAdapters[targetDbKey]`) +- `src/index.js` + - 동적 변수 처리에 `dbAdapters`와 `defaultDbKey` 전달 + +### 📝 문서 +- README/README_KR: v2.1.5 하이라이트, `dynamicVar`의 `db`/`database` 속성 사용 노트 및 예시 추가 +- USER_MANUAL/USER_MANUAL_KR: 동적 변수 속성 및 변수별 DB 라우팅 동작 문서화 +- CHANGELOG/CHANGELOG_KR: v2.1.5 항목 추가 + ## v2.1.4-beta(v1.3.4) - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) ### ✨ 변경 사항 diff --git a/README.md b/README.md index 15454a4..62cb740 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ A Node.js-based tool for generating Excel files from SQL query results. +## v2.1.5-beta(v1.3.5) Highlights + +- DynamicVar DB routing + - `dynamicVar` now supports `db` (alias of `database`) attribute in XML. + - Each dynamic variable executes on its specified DB adapter (falls back to default DB when omitted). +- XML validation update + - `queryDef` now allows `db` attribute in XML schema validation. Note: current execution still uses sheet-level `db` or global default; `queryDef.db` is for future use/documentation. + ## v2.1.4-beta(v1.3.4) Highlights - Adapter-level DB connection test queries @@ -110,6 +118,10 @@ node app.js --mode=export --query=./queries/sample-queries.json node app.js --mode=help ``` +Notes: +- Attributes supported on `dynamicVar`: `name`, `description`, `type`, `db`, `database` (`db` is an alias). When both are present, `database` takes precedence. +- `queryDef` accepts `db` for validation purposes; execution DB is determined by sheet's `db` or the global default DB. + #### Standalone EXE ```bash sql2excel.exe --mode=validate --xml=./queries/sample-queries.xml @@ -391,7 +403,7 @@ The tool supports dynamic variables that can extract data at runtime and use it ```xml - + @@ -399,7 +411,7 @@ The tool supports dynamic variables that can extract data at runtime and use it - + diff --git a/README_KR.md b/README_KR.md index 6ffaf85..94c5521 100644 --- a/README_KR.md +++ b/README_KR.md @@ -2,6 +2,14 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니다. +## v2.1.5-beta(v1.3.5) 하이라이트 + +- 동적 변수 DB 라우팅 + - XML의 `dynamicVar`에서 `db`(= `database` 별칭) 속성 지원. + - 각 동적 변수는 지정한 DB 어댑터에서 실행되며, 미지정 시 기본 DB 사용. +- XML 검증 업데이트 + - XML 스키마 검증에서 `queryDef`의 `db` 속성을 허용. 주의: 현재 실행 DB는 시트의 `db` 또는 전역 기본 DB가 사용되며, `queryDef.db`는 향후 문서/확장용. + ## v2.1.4-beta(v1.3.4) 하이라이트 - 어댑터별 DB 연결 테스트 쿼리 도입 @@ -110,6 +118,10 @@ node app.js --mode=export --query=./queries/sample-queries.json node app.js --mode=help ``` +참고: +- `dynamicVar`에서 지원하는 속성: `name`, `description`, `type`, `db`, `database` (`db`는 별칭). 둘 다 있으면 `database`가 우선합니다. +- `queryDef`는 검증 목적상 `db`를 허용합니다. 실제 실행 DB는 시트의 `db` 혹은 전역 기본 DB가 사용됩니다. + #### 독립 실행 파일(EXE) ```bash sql2excel.exe --mode=validate --xml=./queries/sample-queries.xml @@ -391,7 +403,7 @@ node src/excel-cli.js export --xml ./queries/sales-report.xml \ ```xml - + @@ -399,7 +411,7 @@ node src/excel-cli.js export --xml ./queries/sales-report.xml \ - + diff --git a/USER_MANUAL.md b/USER_MANUAL.md index cabcde9..2e8507f 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -19,6 +19,14 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL query results with advanced styling, template support, and standalone executable distribution. +### What's New (v2.1.5-beta, v1.3.5) + +- DynamicVar DB routing + - XML `dynamicVar` supports `db` (alias of `database`) attribute + - Each dynamic variable runs on its specified DB adapter; falls back to default DB if omitted +- XML validation update + - `queryDef` accepts `db` in schema validation (execution DB is still determined by sheet `db` or global default) + ### What's New (v2.1.4-beta, v1.3.4) - Adapter-level DB connection test queries @@ -527,15 +535,15 @@ The tool supports advanced dynamic variables that can extract data at runtime an #### XML Configuration ```xml - - + + - - + + @@ -559,6 +567,10 @@ WHERE CustomerID IN (${customerData.CustomerID}) 4. **Performance**: Variables are executed once and cached for the entire export 5. **Debug Mode**: Enable with `DEBUG_VARIABLES=true` for detailed variable substitution +Notes: +- Supported `dynamicVar` attributes: `name`, `description`, `type`, `db`, `database` (`db` is an alias). If both are present, `database` takes precedence. +- `queryDef` accepts `db` in XML validation only; runtime execution DB is selected from the sheet's `db` or the global default DB. + ## 🕒 Custom Date/Time Variables SQL2Excel provides a powerful custom date variable system that allows you to display current date and time in any format you want. These variables can be used in queries, file names, and any text content. diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index a5a0d91..26c9be9 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -19,6 +19,14 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 기능을 갖춘 SQL 쿼리 결과로 엑셀 파일을 생성하는 강력한 Node.js 기반 도구입니다. +### v2.1.5-beta(v1.3.5) 주요 변경 + +- 동적 변수 DB 라우팅 + - XML `dynamicVar`에서 `db` 속성 지원 (`database`의 별칭) + - 각 동적 변수는 지정된 DB 어댑터에서 실행, 미지정 시 전역 기본 DB 사용 +- XML 검증 업데이트 + - XML 스키마 검증에서 `queryDef`의 `db` 속성 허용 (실행 DB는 여전히 시트 `db` 또는 전역 기본 DB로 결정) + ### v2.1.4-beta(v1.3.4) 주요 변경 - 어댑터별 DB 연결 테스트 쿼리 도입 @@ -539,15 +547,15 @@ node src/excel-cli.js export --xml queries.xml --style modern #### XML 구성 ```xml - - + + - - + + @@ -571,6 +579,10 @@ WHERE CustomerID IN (${customerData.CustomerID}) 4. **성능**: 변수는 한 번 실행되고 전체 내보내기에 대해 캐시됩니다 5. **디버그 모드**: 자세한 변수 치환을 위해 `DEBUG_VARIABLES=true`로 활성화 +참고: +- `dynamicVar`에서 지원하는 속성: `name`, `description`, `type`, `db`, `database` (`db`는 별칭). 둘 다 있으면 `database`가 우선합니다. +- `queryDef`는 XML 검증에서 `db` 속성을 허용합니다. 실행 시점의 DB는 시트의 `db` 또는 전역 기본 DB로 결정됩니다. + ## 🕒 커스텀 날짜/시간 변수 SQL2Excel은 원하는 형식으로 현재 날짜와 시간을 표시할 수 있는 강력한 커스텀 날짜 변수 시스템을 제공합니다. 이러한 변수는 쿼리, 파일 이름 및 모든 텍스트 콘텐츠에서 사용할 수 있습니다. diff --git a/package.json b/package.json index 469e9d7..5e4994f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "2.1.4-beta", + "version": "2.1.5-beta", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { From 20378edcc98186c34841168e009dcc463abd4090 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 18:41:33 +0900 Subject: [PATCH 21/25] Add sql script for mssql db --- resources/create_sample_tables.sql | 182 ----------------- resources/create_sample_tables_mssql.sql | 242 +++++++++++++++++++++++ resources/drop_sample_tables.sql | 20 -- resources/drop_sample_tables_mssql.sql | 34 ++++ 4 files changed, 276 insertions(+), 202 deletions(-) delete mode 100644 resources/create_sample_tables.sql create mode 100644 resources/create_sample_tables_mssql.sql delete mode 100644 resources/drop_sample_tables.sql create mode 100644 resources/drop_sample_tables_mssql.sql diff --git a/resources/create_sample_tables.sql b/resources/create_sample_tables.sql deleted file mode 100644 index 7a8f34c..0000000 --- a/resources/create_sample_tables.sql +++ /dev/null @@ -1,182 +0,0 @@ --- ======================================== --- 샘플 테이블 생성 스크립트 --- Microsoft SQL Server용 --- ======================================== --- --- 시간 설정 참고: --- SQL Server에서 GETDATE()는 서버의 현지 시각을 반환합니다. --- 한국 표준시(KST)로 설정하려면 서버 타임존을 확인하세요. --- --- ======================================== - -USE [master] -GO - --- 샘플 데이터베이스 생성 (존재하지 않는 경우) -IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'SampleDB') -BEGIN - CREATE DATABASE [SampleDB] -END -GO - -USE [SampleDB] -GO - --- ======================================== --- 1. Customers 테이블 생성 --- ======================================== - --- 기존 테이블이 있으면 삭제 -IF OBJECT_ID('dbo.Customers', 'U') IS NOT NULL - DROP TABLE dbo.Customers -GO - -CREATE TABLE dbo.Customers ( - CustomerID int IDENTITY(1,1) NOT NULL, - CustomerCode nvarchar(20) NOT NULL, - CustomerName nvarchar(100) NOT NULL, - ContactName nvarchar(50) NULL, - Email nvarchar(100) NULL, - Phone nvarchar(20) NULL, - Address nvarchar(200) NULL, - City nvarchar(50) NULL, - Region nvarchar(50) NULL, - PostalCode nvarchar(10) NULL, - Country nvarchar(50) NULL, - CustomerType nvarchar(20) DEFAULT 'Regular', - CreditLimit decimal(15,2) DEFAULT 0, - IsActive bit DEFAULT 1, - CreatedDate datetime2(7) DEFAULT GETDATE(), - LastUpdated datetime2(7) DEFAULT GETDATE(), - - CONSTRAINT PK_Customers PRIMARY KEY CLUSTERED (CustomerID ASC), - CONSTRAINT UK_Customers_Code UNIQUE (CustomerCode) -) -GO - --- 인덱스 생성 -CREATE NONCLUSTERED INDEX IX_Customers_Name ON dbo.Customers (CustomerName) -CREATE NONCLUSTERED INDEX IX_Customers_City ON dbo.Customers (City) -CREATE NONCLUSTERED INDEX IX_Customers_Region ON dbo.Customers (Region) -CREATE NONCLUSTERED INDEX IX_Customers_Type ON dbo.Customers (CustomerType) -GO - --- ======================================== --- 2. Orders 테이블 생성 --- ======================================== - --- 기존 테이블이 있으면 삭제 -IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL - DROP TABLE dbo.Orders -GO - -CREATE TABLE dbo.Orders ( - OrderID int IDENTITY(1,1) NOT NULL, - OrderNumber nvarchar(30) NOT NULL, - CustomerID int NOT NULL, - OrderDate datetime2(7) NOT NULL, - RequiredDate datetime2(7) NULL, - ShippedDate datetime2(7) NULL, - OrderStatus nvarchar(20) DEFAULT 'Pending', - ShipVia nvarchar(50) NULL, - Freight decimal(10,2) DEFAULT 0, - ShipName nvarchar(100) NULL, - ShipAddress nvarchar(200) NULL, - ShipCity nvarchar(50) NULL, - ShipRegion nvarchar(50) NULL, - ShipPostalCode nvarchar(10) NULL, - ShipCountry nvarchar(50) NULL, - SubTotal decimal(15,2) DEFAULT 0, - TaxAmount decimal(10,2) DEFAULT 0, - TotalAmount decimal(15,2) DEFAULT 0, - PaymentMethod nvarchar(30) NULL, - PaymentStatus nvarchar(20) DEFAULT 'Unpaid', - EmployeeID int NULL, - Notes nvarchar(500) NULL, - CreatedDate datetime2(7) DEFAULT GETDATE(), - LastUpdated datetime2(7) DEFAULT GETDATE(), - - CONSTRAINT PK_Orders PRIMARY KEY CLUSTERED (OrderID ASC), - CONSTRAINT UK_Orders_Number UNIQUE (OrderNumber), - CONSTRAINT FK_Orders_Customers FOREIGN KEY (CustomerID) - REFERENCES dbo.Customers (CustomerID) -) -GO - --- 인덱스 생성 -CREATE NONCLUSTERED INDEX IX_Orders_CustomerID ON dbo.Orders (CustomerID) -CREATE NONCLUSTERED INDEX IX_Orders_OrderDate ON dbo.Orders (OrderDate) -CREATE NONCLUSTERED INDEX IX_Orders_Status ON dbo.Orders (OrderStatus) -CREATE NONCLUSTERED INDEX IX_Orders_PaymentStatus ON dbo.Orders (PaymentStatus) -CREATE NONCLUSTERED INDEX IX_Orders_ShippedDate ON dbo.Orders (ShippedDate) -GO - --- ======================================== --- 3. OrderDetails 테이블 생성 (추가) --- ======================================== - --- 기존 테이블이 있으면 삭제 -IF OBJECT_ID('dbo.OrderDetails', 'U') IS NOT NULL - DROP TABLE dbo.OrderDetails -GO - -CREATE TABLE dbo.OrderDetails ( - OrderDetailID int IDENTITY(1,1) NOT NULL, - OrderID int NOT NULL, - ProductCode nvarchar(30) NOT NULL, - ProductName nvarchar(100) NOT NULL, - UnitPrice decimal(10,2) NOT NULL, - Quantity int NOT NULL, - Discount decimal(5,2) DEFAULT 0, - LineTotal AS (UnitPrice * Quantity * (1 - Discount/100)) PERSISTED, - - CONSTRAINT PK_OrderDetails PRIMARY KEY CLUSTERED (OrderDetailID ASC), - CONSTRAINT FK_OrderDetails_Orders FOREIGN KEY (OrderID) - REFERENCES dbo.Orders (OrderID) ON DELETE CASCADE -) -GO - --- 인덱스 생성 -CREATE NONCLUSTERED INDEX IX_OrderDetails_OrderID ON dbo.OrderDetails (OrderID) -CREATE NONCLUSTERED INDEX IX_OrderDetails_ProductCode ON dbo.OrderDetails (ProductCode) -GO - --- ======================================== --- 4. 뷰 생성 (주문 요약) --- ======================================== - -IF OBJECT_ID('dbo.vw_OrderSummary', 'V') IS NOT NULL - DROP VIEW dbo.vw_OrderSummary -GO - -CREATE VIEW dbo.vw_OrderSummary -AS -SELECT - o.OrderID, - o.OrderNumber, - o.OrderDate, - c.CustomerCode, - c.CustomerName, - c.City as CustomerCity, - c.Region as CustomerRegion, - o.OrderStatus, - o.PaymentStatus, - o.TotalAmount, - COUNT(od.OrderDetailID) as ItemCount, - SUM(od.Quantity) as TotalQuantity, - o.CreatedDate -FROM dbo.Orders o - INNER JOIN dbo.Customers c ON o.CustomerID = c.CustomerID - LEFT JOIN dbo.OrderDetails od ON o.OrderID = od.OrderID -GROUP BY - o.OrderID, o.OrderNumber, o.OrderDate, - c.CustomerCode, c.CustomerName, c.City, c.Region, - o.OrderStatus, o.PaymentStatus, o.TotalAmount, o.CreatedDate -GO - -PRINT '테이블 생성이 완료되었습니다.' -PRINT '- Customers 테이블' -PRINT '- Orders 테이블' -PRINT '- OrderDetails 테이블' -PRINT '- vw_OrderSummary 뷰' -GO \ No newline at end of file diff --git a/resources/create_sample_tables_mssql.sql b/resources/create_sample_tables_mssql.sql new file mode 100644 index 0000000..0a2e2e6 --- /dev/null +++ b/resources/create_sample_tables_mssql.sql @@ -0,0 +1,242 @@ +-- ======================================== +-- 샘플 테이블 생성 스크립트 +-- Microsoft SQL Server 용 (SQL Server 2012+ 권장) +-- ======================================== + +SET NOCOUNT ON; + +-- 기존 객체 삭제 (존재 시) +IF OBJECT_ID('dbo.vw_OrderSummary', 'V') IS NOT NULL DROP VIEW dbo.vw_OrderSummary; +IF OBJECT_ID('dbo.OrderDetails', 'U') IS NOT NULL DROP TABLE dbo.OrderDetails; +IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL DROP TABLE dbo.Orders; +IF OBJECT_ID('dbo.Products', 'U') IS NOT NULL DROP TABLE dbo.Products; +IF OBJECT_ID('dbo.Employees', 'U') IS NOT NULL DROP TABLE dbo.Employees; +IF OBJECT_ID('dbo.Customers', 'U') IS NOT NULL DROP TABLE dbo.Customers; +GO + +-- ======================================== +-- 1. Customers 테이블 +-- ======================================== +CREATE TABLE dbo.Customers ( + CustomerID INT IDENTITY(1,1) NOT NULL, + CustomerCode VARCHAR(20) NOT NULL, + CustomerName VARCHAR(100) NOT NULL, + ContactName VARCHAR(50) NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Address VARCHAR(200) NULL, + City VARCHAR(50) NULL, + Region VARCHAR(50) NULL, + PostalCode VARCHAR(10) NULL, + Country VARCHAR(50) NULL, + CustomerType VARCHAR(20) CONSTRAINT DF_Customers_CustomerType DEFAULT ('Regular'), + CreditLimit DECIMAL(15,2) CONSTRAINT DF_Customers_CreditLimit DEFAULT (0), + IsActive BIT CONSTRAINT DF_Customers_IsActive DEFAULT (1), + CreatedDate DATETIME2 CONSTRAINT DF_Customers_CreatedDate DEFAULT (SYSDATETIME()), + LastUpdated DATETIME2 CONSTRAINT DF_Customers_LastUpdated DEFAULT (SYSDATETIME()), + CONSTRAINT PK_Customers PRIMARY KEY (CustomerID), + CONSTRAINT UK_Customers_Code UNIQUE (CustomerCode) +); +GO + +CREATE INDEX IX_Customers_Name ON dbo.Customers (CustomerName); +CREATE INDEX IX_Customers_City ON dbo.Customers (City); +CREATE INDEX IX_Customers_Region ON dbo.Customers (Region); +CREATE INDEX IX_Customers_Type ON dbo.Customers (CustomerType); +GO + +-- LastUpdated 자동 업데이트 트리거 +IF OBJECT_ID('dbo.trg_customers_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_customers_modtime; +GO +CREATE TRIGGER dbo.trg_customers_modtime +ON dbo.Customers +AFTER UPDATE +AS +BEGIN + SET NOCOUNT ON; + UPDATE c + SET LastUpdated = SYSDATETIME() + FROM dbo.Customers c + INNER JOIN inserted i ON c.CustomerID = i.CustomerID; +END; +GO + +-- ======================================== +-- 2. Orders 테이블 +-- ======================================== +CREATE TABLE dbo.Orders ( + OrderID INT IDENTITY(1,1) NOT NULL, + OrderNumber VARCHAR(30) NOT NULL, + CustomerID INT NOT NULL, + OrderDate DATETIME2 NOT NULL, + RequiredDate DATETIME2 NULL, + ShippedDate DATETIME2 NULL, + OrderStatus VARCHAR(20) CONSTRAINT DF_Orders_OrderStatus DEFAULT ('Pending'), + SubTotal DECIMAL(15,2) CONSTRAINT DF_Orders_SubTotal DEFAULT (0), + TaxAmount DECIMAL(15,2) CONSTRAINT DF_Orders_TaxAmount DEFAULT (0), + TotalAmount DECIMAL(15,2) CONSTRAINT DF_Orders_TotalAmount DEFAULT (0), + PaymentMethod VARCHAR(30) NULL, + PaymentStatus VARCHAR(20) CONSTRAINT DF_Orders_PaymentStatus DEFAULT ('Unpaid'), + EmployeeID INT NULL, + Notes VARCHAR(500) NULL, + CreatedDate DATETIME2 CONSTRAINT DF_Orders_CreatedDate DEFAULT (SYSDATETIME()), + LastUpdated DATETIME2 CONSTRAINT DF_Orders_LastUpdated DEFAULT (SYSDATETIME()), + CONSTRAINT PK_Orders PRIMARY KEY (OrderID), + CONSTRAINT UK_Orders_Number UNIQUE (OrderNumber), + CONSTRAINT FK_Orders_Customers FOREIGN KEY (CustomerID) REFERENCES dbo.Customers(CustomerID) +); +GO + +CREATE INDEX IX_Orders_CustomerID ON dbo.Orders (CustomerID); +CREATE INDEX IX_Orders_OrderDate ON dbo.Orders (OrderDate); +CREATE INDEX IX_Orders_Status ON dbo.Orders (OrderStatus); +CREATE INDEX IX_Orders_PaymentStatus ON dbo.Orders (PaymentStatus); +CREATE INDEX IX_Orders_ShippedDate ON dbo.Orders (ShippedDate); +GO + +IF OBJECT_ID('dbo.trg_orders_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_orders_modtime; +GO +CREATE TRIGGER dbo.trg_orders_modtime +ON dbo.Orders +AFTER UPDATE +AS +BEGIN + SET NOCOUNT ON; + UPDATE o + SET LastUpdated = SYSDATETIME() + FROM dbo.Orders o + INNER JOIN inserted i ON o.OrderID = i.OrderID; +END; +GO + +-- ======================================== +-- 3. Products 테이블 +-- ======================================== +CREATE TABLE dbo.Products ( + ProductID INT IDENTITY(1,1) NOT NULL, + ProductCode VARCHAR(20) NOT NULL, + ProductName VARCHAR(100) NOT NULL, + Category VARCHAR(50) NULL, + UnitPrice DECIMAL(15,2) CONSTRAINT DF_Products_UnitPrice DEFAULT (0), + UnitsInStock INT CONSTRAINT DF_Products_UnitsInStock DEFAULT (0), + UnitsOnOrder INT CONSTRAINT DF_Products_UnitsOnOrder DEFAULT (0), + ReorderLevel INT CONSTRAINT DF_Products_ReorderLevel DEFAULT (0), + Discontinued BIT CONSTRAINT DF_Products_Discontinued DEFAULT (0), + Description NVARCHAR(MAX) NULL, + CreatedDate DATETIME2 CONSTRAINT DF_Products_CreatedDate DEFAULT (SYSDATETIME()), + LastUpdated DATETIME2 CONSTRAINT DF_Products_LastUpdated DEFAULT (SYSDATETIME()), + CONSTRAINT PK_Products PRIMARY KEY (ProductID), + CONSTRAINT UK_Products_Code UNIQUE (ProductCode) +); +GO + +CREATE INDEX IX_Products_Name ON dbo.Products (ProductName); +CREATE INDEX IX_Products_Category ON dbo.Products (Category); +CREATE INDEX IX_Products_Price ON dbo.Products (UnitPrice); +GO + +IF OBJECT_ID('dbo.trg_products_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_products_modtime; +GO +CREATE TRIGGER dbo.trg_products_modtime +ON dbo.Products +AFTER UPDATE +AS +BEGIN + SET NOCOUNT ON; + UPDATE p + SET LastUpdated = SYSDATETIME() + FROM dbo.Products p + INNER JOIN inserted i ON p.ProductID = i.ProductID; +END; +GO + +-- ======================================== +-- 4. OrderDetails 테이블 +-- ======================================== +CREATE TABLE dbo.OrderDetails ( + OrderDetailID INT IDENTITY(1,1) NOT NULL, + OrderID INT NOT NULL, + ProductID INT NOT NULL, + UnitPrice DECIMAL(15,2) NOT NULL, + Quantity INT NOT NULL, + Discount DECIMAL(5,2) CONSTRAINT DF_OrderDetails_Discount DEFAULT (0), + LineTotal AS (UnitPrice * Quantity * (1 - (Discount/100.0))) PERSISTED, + CreatedDate DATETIME2 CONSTRAINT DF_OrderDetails_CreatedDate DEFAULT (SYSDATETIME()), + CONSTRAINT PK_OrderDetails PRIMARY KEY (OrderDetailID), + CONSTRAINT FK_OrderDetails_Orders FOREIGN KEY (OrderID) REFERENCES dbo.Orders(OrderID) ON DELETE CASCADE, + CONSTRAINT FK_OrderDetails_Products FOREIGN KEY (ProductID) REFERENCES dbo.Products(ProductID) +); +GO + +CREATE INDEX IX_OrderDetails_OrderID ON dbo.OrderDetails (OrderID); +CREATE INDEX IX_OrderDetails_ProductID ON dbo.OrderDetails (ProductID); +GO + +-- ======================================== +-- 5. Employees 테이블 +-- ======================================== +CREATE TABLE dbo.Employees ( + EmployeeID INT IDENTITY(1,1) NOT NULL, + EmployeeCode VARCHAR(20) NOT NULL, + FirstName VARCHAR(50) NOT NULL, + LastName VARCHAR(50) NOT NULL, + Title VARCHAR(50) NULL, + BirthDate DATE NULL, + HireDate DATE NULL, + Email VARCHAR(100) NULL, + Phone VARCHAR(20) NULL, + Department VARCHAR(50) NULL, + Salary DECIMAL(15,2) NULL, + ReportsTo INT NULL, + IsActive BIT CONSTRAINT DF_Employees_IsActive DEFAULT (1), + CreatedDate DATETIME2 CONSTRAINT DF_Employees_CreatedDate DEFAULT (SYSDATETIME()), + LastUpdated DATETIME2 CONSTRAINT DF_Employees_LastUpdated DEFAULT (SYSDATETIME()), + CONSTRAINT PK_Employees PRIMARY KEY (EmployeeID), + CONSTRAINT UK_Employees_Code UNIQUE (EmployeeCode), + CONSTRAINT FK_Employees_ReportsTo FOREIGN KEY (ReportsTo) REFERENCES dbo.Employees(EmployeeID) +); +GO + +CREATE INDEX IX_Employees_Name ON dbo.Employees (LastName, FirstName); +CREATE INDEX IX_Employees_Department ON dbo.Employees (Department); +CREATE INDEX IX_Employees_ReportsTo ON dbo.Employees (ReportsTo); +GO + +IF OBJECT_ID('dbo.trg_employees_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_employees_modtime; +GO +CREATE TRIGGER dbo.trg_employees_modtime +ON dbo.Employees +AFTER UPDATE +AS +BEGIN + SET NOCOUNT ON; + UPDATE e + SET LastUpdated = SYSDATETIME() + FROM dbo.Employees e + INNER JOIN inserted i ON e.EmployeeID = i.EmployeeID; +END; +GO + +-- ======================================== +-- 6. 주문 요약 뷰 +-- ======================================== +CREATE VIEW dbo.vw_OrderSummary AS +SELECT + o.OrderID, + o.OrderNumber, + o.OrderDate, + c.CustomerCode, + c.CustomerName, + c.City AS CustomerCity, + c.Region AS CustomerRegion, + o.OrderStatus, + o.PaymentStatus, + o.TotalAmount, + (SELECT COUNT(*) FROM dbo.OrderDetails od WHERE od.OrderID = o.OrderID) AS ItemCount, + (SELECT ISNULL(SUM(od.Quantity),0) FROM dbo.OrderDetails od WHERE od.OrderID = o.OrderID) AS TotalQuantity, + o.CreatedDate +FROM dbo.Orders o +JOIN dbo.Customers c ON o.CustomerID = c.CustomerID; +GO + +PRINT 'MSSQL용 샘플 테이블 생성 완료'; diff --git a/resources/drop_sample_tables.sql b/resources/drop_sample_tables.sql deleted file mode 100644 index a32baed..0000000 --- a/resources/drop_sample_tables.sql +++ /dev/null @@ -1,20 +0,0 @@ - - ------------------------------------------------------------ --- 외래키 삭제 ------------------------------------------------------------ -ALTER TABLE OrderDetails DROP CONSTRAINT FK_OrderDetails_Orders; -ALTER TABLE Orders DROP CONSTRAINT FK_Orders_Customers; - - - ------------------------------------------------------------ --- 테이블 삭제 ------------------------------------------------------------ -DROP TABLE OrderDetails; -DROP TABLE Orders; -DROP TABLE Customers; - - - - diff --git a/resources/drop_sample_tables_mssql.sql b/resources/drop_sample_tables_mssql.sql new file mode 100644 index 0000000..2c8a02b --- /dev/null +++ b/resources/drop_sample_tables_mssql.sql @@ -0,0 +1,34 @@ +-- ======================================== +-- 샘플 테이블/뷰 삭제 스크립트 (MSSQL) +-- 의존성 순서에 맞춰 안전하게 드롭 +-- ======================================== + +SET NOCOUNT ON; + +-- 1) 뷰 드롭 +IF OBJECT_ID('dbo.vw_OrderSummary', 'V') IS NOT NULL DROP VIEW dbo.vw_OrderSummary; +GO + +-- 2) 트리거 드롭 (존재 시) +IF OBJECT_ID('dbo.trg_customers_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_customers_modtime; +IF OBJECT_ID('dbo.trg_orders_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_orders_modtime; +IF OBJECT_ID('dbo.trg_products_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_products_modtime; +IF OBJECT_ID('dbo.trg_employees_modtime', 'TR') IS NOT NULL DROP TRIGGER dbo.trg_employees_modtime; +GO + +-- 3) 외래키 제약 해제 (존재 시) +IF OBJECT_ID('dbo.FK_OrderDetails_Orders', 'F') IS NOT NULL ALTER TABLE dbo.OrderDetails DROP CONSTRAINT FK_OrderDetails_Orders; +IF OBJECT_ID('dbo.FK_OrderDetails_Products', 'F') IS NOT NULL ALTER TABLE dbo.OrderDetails DROP CONSTRAINT FK_OrderDetails_Products; +IF OBJECT_ID('dbo.FK_Employees_ReportsTo', 'F') IS NOT NULL ALTER TABLE dbo.Employees DROP CONSTRAINT FK_Employees_ReportsTo; +IF OBJECT_ID('dbo.FK_Orders_Customers', 'F') IS NOT NULL ALTER TABLE dbo.Orders DROP CONSTRAINT FK_Orders_Customers; +GO + +-- 4) 테이블 드롭 (자식 → 부모 순서) +IF OBJECT_ID('dbo.OrderDetails', 'U') IS NOT NULL DROP TABLE dbo.OrderDetails; +IF OBJECT_ID('dbo.Orders', 'U') IS NOT NULL DROP TABLE dbo.Orders; +IF OBJECT_ID('dbo.Products', 'U') IS NOT NULL DROP TABLE dbo.Products; +IF OBJECT_ID('dbo.Employees', 'U') IS NOT NULL DROP TABLE dbo.Employees; +IF OBJECT_ID('dbo.Customers', 'U') IS NOT NULL DROP TABLE dbo.Customers; +GO + +PRINT 'MSSQL 샘플 객체 삭제 완료'; From 68409e8b25a03e34b2c8341b15caaa037e3b25b3 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 19:00:03 +0900 Subject: [PATCH 22/25] Modification document for Multi databases support feature --- README.md | 12 ++++++++++++ README_KR.md | 12 ++++++++++++ USER_MANUAL.md | 25 +++++++++++++++++++++++-- USER_MANUAL_KR.md | 26 +++++++++++++++++++++----- package.json | 2 +- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 62cb740..7f137a4 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,18 @@ A Node.js-based tool for generating Excel files from SQL query results. - 🔧 **Input Validation**: Automatic whitespace trimming for file path inputs - 🗂️ **Filename Variables**: Use `${DATE:...}`, `${DATE.TZ:...}`, and `${DB_NAME}` in `excel.output` (also supports custom `$(DB_NAME}`) +## 🔗 Multi-Database Usage + +- **Supported drivers**: MSSQL (`mssql`), MySQL (`mysql2`), MariaDB (`mysql2`), PostgreSQL (`pg`), SQLite (`better-sqlite3`), Oracle (`oracledb`) +- **Configuration**: `config/dbinfo.json` with per-DB keys and `type` (optional for MSSQL default) +- **Runtime DB selection precedence** + - Default DB key: `--db` (CLI) > `excel.db` (XML/JSON) + - Sheet: `sheet.db` > Default DB + - Dynamic variables: `dynamicVar.database` or `dynamicVar.db` > Default DB +- **Connection test** + - Dev: `npm run list-dbs` + - EXE: `sql2excel.exe list-dbs` + ## v2.1.2-beta(v1.3.2) Highlights - Per-sheet export directory naming simplified diff --git a/README_KR.md b/README_KR.md index 94c5521..c5e2171 100644 --- a/README_KR.md +++ b/README_KR.md @@ -50,6 +50,18 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 🔧 **입력 유효성 검증**: 파일 경로 입력에 대한 자동 공백 제거 - 🗂️ **파일명 변수**: `excel.output`에서 `${DATE:...}`, `${DATE.TZ:...}`, `${DB_NAME}` 사용 가능 (커스텀 `$(DB_NAME}`도 지원) +## 🔗 다중 데이터베이스 사용 + +- **지원 드라이버**: MSSQL(`mssql`), MySQL(`mysql2`), MariaDB(`mysql2`), PostgreSQL(`pg`), SQLite(`better-sqlite3`), Oracle(`oracledb`) +- **설정 파일**: `config/dbinfo.json`에 DB 키별 접속 정보와 `type` 지정 (MSSQL은 생략 시 기본값) +- **런타임 DB 선택 우선순위** + - 기본 DB 키: `--db`(CLI) > `excel.db`(XML/JSON) + - 시트: `sheet.db` > 기본 DB + - 동적 변수: `dynamicVar.database` 또는 `dynamicVar.db` > 기본 DB +- **연결 테스트** + - 개발: `npm run list-dbs` + - EXE: `sql2excel.exe list-dbs` + ## v2.1.2-beta(v1.3.2) 하이라이트 - 시트별 내보내기 디렉토리 명명 단순화 diff --git a/USER_MANUAL.md b/USER_MANUAL.md index 2e8507f..5ed24a5 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -122,7 +122,7 @@ npm run build ### 3. Database Connection Setup Create `config/dbinfo.json` file: -#### Multi-Database Support (v1.3.0+) +#### Multi-Database Support (v2.0.0+) ```json { "sampleDB": { @@ -454,6 +454,20 @@ sql2excel.exe --mode=help } ``` +## 🔗 Multi-Database + +This tool supports multiple databases with unified adapters and flexible routing. + +- **Supported drivers**: MSSQL (`mssql`), MySQL (`mysql2`), MariaDB (`mysql2`), PostgreSQL (`pg`), SQLite (`better-sqlite3`), Oracle (`oracledb`) +- **Configuration**: Define multiple DB keys in `config/dbinfo.json` with optional `type` (defaults to `mssql`) and connection fields. See examples above and in “Multi-Database Support (v2.0.0+)”. +- **Runtime DB selection precedence (v2.1.5+)** + - Default DB key: CLI `--db` > `excel.db` + - Per sheet: `sheet.db` overrides default DB + - Dynamic variables: `dynamicVar.database` or `dynamicVar.db` overrides default DB +- **Mixed-DB usage**: You can query different DBs within a single export. See “Multi-Database Support (v2.0.0+)” for XML/JSON examples. +- **Connection test**: Validate connectivity before export with `node src/excel-cli.js list-dbs` (dev) or `sql2excel.exe list-dbs` (EXE). +- **Adapter behavior**: Row limiting and functions are adapted per DB (e.g., MSSQL uses TOP, MySQL/MariaDB use LIMIT). + ## 🎨 Template Style System SQL2Excel includes a comprehensive template style system with pre-defined Excel styling templates. @@ -824,7 +838,7 @@ This feature works automatically - no configuration required! ## 🎨 Advanced Features -### 1. Multi-Database Support (v1.3.0+) +### 1. Multi-Database Support (v2.0.0+) SQL2Excel now supports multiple database types with a unified interface: @@ -947,6 +961,13 @@ node src/excel-cli.js list-dbs sql2excel-v1.3.0.exe list-dbs ``` +#### Runtime DB selection precedence (v2.1.5+) + +- Default DB key: CLI `--db` > `excel.db` +- Per sheet: `sheet.db` overrides default DB +- Dynamic variables: `dynamicVar.database` or `dynamicVar.db` overrides default DB +- Tip: Use `list-dbs` (above) to verify connections before export + ### 2. Excel Styling #### Font Styling diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index 26c9be9..bf172ac 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -121,7 +121,7 @@ npm run build ### 3. 데이터베이스 연결 설정 `config/dbinfo.json` 파일을 생성하세요: -#### 다중 데이터베이스 지원 (v1.3.0+) +#### 다중 데이터베이스 지원 (v2.0.0+) ```json { "sampleDB": { @@ -466,12 +466,21 @@ sql2excel.exe --mode=help - 내부 줄바꿈(\r/\n)은 CSV/TXT 모두 공백으로 정규화 - 날짜 직렬화: `yyyy-MM-dd HH:mm:ss` (24시간) -## 🎨 템플릿 스타일 시스템 +## 🔗 다중 데이터베이스 -SQL2Excel은 사전 정의된 엑셀 스타일링 템플릿을 포함한 포괄적인 템플릿 스타일 시스템을 제공합니다. +통합 어댑터와 유연한 라우팅으로 여러 데이터베이스를 지원합니다. -### 사용 가능한 템플릿 스타일 +- **지원 드라이버**: MSSQL(`mssql`), MySQL(`mysql2`), MariaDB(`mysql2`), PostgreSQL(`pg`), SQLite(`better-sqlite3`), Oracle(`oracledb`) +- **설정**: `config/dbinfo.json`에 다수의 DB 키를 정의하고 `type`(미지정 시 `mssql`)과 접속 정보를 설정하세요. 상세 예시는 위 “다중 데이터베이스 지원 (v2.0.0+)” 섹션 참고. +- **런타임 DB 선택 우선순위 (v2.1.5+) + - 기본 DB 키: CLI `--db` > `excel.db` + - 시트별: `sheet.db`가 기본 DB를 오버라이드 + - 동적 변수: `dynamicVar.database` 또는 `dynamicVar.db`가 기본 DB를 오버라이드 +- **혼합 사용**: 하나의 내보내기에서 서로 다른 DB를 동시에 사용할 수 있습니다. XML/JSON 예시는 “다중 데이터베이스 지원 (v2.0.0+)” 섹션을 참고하세요. +- **연결 테스트**: 내보내기 전 `node src/excel-cli.js list-dbs`(개발) 또는 `sql2excel.exe list-dbs`(EXE)로 확인하세요. +- **어댑터 동작**: 행 제한과 함수가 DB별로 자동 조정됩니다 (예: MSSQL=TOP, MySQL/MariaDB=LIMIT). +## 🎨 템플릿 스타일 시스템 | 스타일 ID | 이름 | 설명 | |----------|------|------| | `default` | 기본 스타일 | 기본 엑셀 스타일 | @@ -836,7 +845,7 @@ SQL2Excel은 생성된 각 엑셀 시트에 자동으로 생성 타임스탬프 ## 🎨 고급 기능 -### 1. 다중 데이터베이스 지원 (v1.3.0+) +### 1. 다중 데이터베이스 지원 (v2.0.0+) SQL2Excel은 이제 통합 인터페이스로 여러 데이터베이스 타입을 지원합니다: @@ -959,6 +968,13 @@ node src/excel-cli.js list-dbs sql2excel-v1.3.0.exe list-dbs ``` +#### 런타임 DB 선택 우선순위 (v2.1.5+) + +- 기본 DB 키: CLI `--db` > `excel.db` +- 시트별: `sheet.db`가 기본 DB를 오버라이드 +- 동적 변수: `dynamicVar.database` 또는 `dynamicVar.db`가 기본 DB를 오버라이드 +- 팁: 내보내기 전에 위 `list-dbs`로 연결 상태를 점검하세요 + ### 2. 엑셀 스타일링 #### 글꼴 스타일링 diff --git a/package.json b/package.json index 5e4994f..ba56e4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql2excel", - "version": "2.1.5-beta", + "version": "2.1.5", "description": "SQL 쿼리 결과를 엑셀 파일로 저장하는 도구 (시트별 쿼리, 변수, XML/JSON 지원)", "main": "app.js", "scripts": { From 1603b55604e6f439a55edebc01a09a9ad86b7bbd Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 19:21:53 +0900 Subject: [PATCH 23/25] Updated sample SQL query --- package-lock.json | 4 ++-- queries/queries-with-dynamic-variables.xml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index ded46c6..260d39d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sql2excel", - "version": "1.3.3", + "version": "2.1.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sql2excel", - "version": "1.3.3", + "version": "2.1.5", "dependencies": { "better-sqlite3": "^11.10.0", "exceljs": "^4.3.0", diff --git a/queries/queries-with-dynamic-variables.xml b/queries/queries-with-dynamic-variables.xml index 85be847..fdc80d5 100644 --- a/queries/queries-with-dynamic-variables.xml +++ b/queries/queries-with-dynamic-variables.xml @@ -11,7 +11,7 @@ 2024-01-01 2024-06-30 ["Seoul", "Busan"] - ["ACTIVE", "PENDING", "COMPLETED"] + ["Pending", "Shipped"] [1, 2, 3, 5] 1000 @@ -21,7 +21,7 @@ @@ -40,7 +40,7 @@ @@ -49,7 +49,7 @@ From 8b2b114f92747cb3eb3287922f10d0ae64cf9d4d Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 19:30:49 +0900 Subject: [PATCH 24/25] Updated veriosn history --- CHANGELOG.md | 18 +++++++++--------- CHANGELOG_KR.md | 16 ++++++++-------- README.md | 14 +++++++------- README_KR.md | 14 +++++++------- USER_MANUAL.md | 10 +++++----- USER_MANUAL_KR.md | 10 +++++----- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 096f883..995b091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # SQL2Excel Version History -## v2.1.5-beta(v1.3.5) - DynamicVar DB Routing & XML Validation Update (2025-11-15) +## v2.1.5 - DynamicVar DB Routing & XML Validation Update (2025-11-15) ### ✨ New/Changed - Dynamic variable DB routing @@ -24,7 +24,7 @@ - USER_MANUAL/USER_MANUAL_KR: Documented dynamicVar attributes and per-variable DB routing - CHANGELOG/CHANGELOG_KR: Added v2.1.5 entries -## v2.1.4-beta(v1.3.4) - DB Adapter Test Query & Schema Alignment (2025-11-08) +## v2.1.4(v1.3.4) - DB Adapter Test Query & Schema Alignment (2025-11-08) ### ✨ New/Changed - Adapter-level connection test SQL @@ -59,7 +59,7 @@ ### 📝 Notes - These changes ensure sample data (PostgreSQL) loads cleanly across DBs when schemas are applied accordingly. -## v2.1.4-beta(v1.3.3) - Docs Sync & Version Bump (2025-10-31) +## v2.1.4(v1.3.3) - Docs Sync & Version Bump (2025-10-31) ### ✨ New/Changed - Added `exceptColumns` attribute to exclude specific columns from sheet output @@ -77,7 +77,7 @@ ### 📝 Documentation - README/README_KR, USER_MANUAL/USER_MANUAL_KR, CHANGELOG/CHANGELOG_KR updated accordingly -## v2.1.2-beta(v1.3.2) - CSV/TXT Formatting & Directory Naming (2025-10-31) +## v2.1.2(v1.3.2) - CSV/TXT Formatting & Directory Naming (2025-10-31) ### ✨ New/Changed - Per-sheet export directory naming simplified @@ -102,7 +102,7 @@ - USER_MANUAL/USER_MANUAL_KR: Updated per-sheet export section to reflect new directory naming and formatting rules - CHANGELOG/CHANGELOG_KR: Added v1.3.2 entry -## v2.1.1-beta(v1.3.1) - Filename Variables and DATE Fixes (2025-10-30) +## v2.1.1(v1.3.1) - Filename Variables and DATE Fixes (2025-10-30) ### ✨ New/Changed - Output filename variable enhancements @@ -125,7 +125,7 @@ - USER_MANUAL/USER_MANUAL_KR: Documented filename variables (`DB_NAME`, DATE), lowercase tokens, and local-time behavior - CHANGELOG/CHANGELOG_KR: Added v1.3.1 entry -## v2.1.0-beta(v1.3.0) - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) +## v2.1.0(v1.3.0) - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) ### ✨ New/Changed - Export routing based on output extension @@ -152,7 +152,7 @@ - USER_MANUAL/USER_MANUAL_KR: Added section describing routing, directory/filename rules, and defaults - CHANGELOG/CHANGELOG_KR: Added v1.3.0 entry -## v2.0.11-beta(v1.2.11) - TOC Original Name & Sheet Name Length Warning (2025-10-29) +## v2.0.11(v1.2.11) - TOC Original Name & Sheet Name Length Warning (2025-10-29) ### ✨ New/Changed - Sheet name length > 31 characters is now treated as a warning during validation (no failure) @@ -170,7 +170,7 @@ - README/README_KR: Updated highlights to v1.2.11, described changes - CHANGELOG: Added v1.2.11 entry -## v2.0.10-beta(v1.2.10) - Non-interactive CLI & Docs (2025-10-29) +## v2.0.10(v1.2.10) - Non-interactive CLI & Docs (2025-10-29) ### ✨ New Features @@ -183,7 +183,7 @@ - README.md / README_KR.md: Added "Non-interactive CLI" usage and examples - Updated highlights to v1.2.10 -## v2.0.0-beta - Multi-Database Support (2025-10-22) +## v2.0.0 - Multi-Database Support (2025-10-22) ### ✨ New Features - **Multi-Database Support**: Support for multiple database types beyond MSSQL diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index ec39186..e385f95 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -1,6 +1,6 @@ # SQL2Excel 버전 히스토리 -## v2.1.5-beta(v1.3.5) - 동적 변수 DB 라우팅 & XML 검증 업데이트 (2025-11-15) +## v2.1.5 - 동적 변수 DB 라우팅 & XML 검증 업데이트 (2025-11-15) ### ✨ 변경 사항 - 동적 변수 DB 라우팅 @@ -24,7 +24,7 @@ - USER_MANUAL/USER_MANUAL_KR: 동적 변수 속성 및 변수별 DB 라우팅 동작 문서화 - CHANGELOG/CHANGELOG_KR: v2.1.5 항목 추가 -## v2.1.4-beta(v1.3.4) - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) +## v2.1.4(v1.3.4) - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) ### ✨ 변경 사항 - 어댑터 단위 연결 테스트 SQL 도입 @@ -59,7 +59,7 @@ ### 📝 비고 - 본 변경으로 샘플 데이터(PostgreSQL)가 각 DB 스키마 적용 시 원활히 적재되도록 정합성이 개선되었습니다. -## v2.1.3-beta(v1.3.3) - 문서 동기화 및 버전 올림 (2025-10-31) +## v2.1.3(v1.3.3) - 문서 동기화 및 버전 올림 (2025-10-31) ### ✨ 변경 사항 - 시트에서 특정 컬럼을 결과에서 제외하는 `exceptColumns` 속성 추가 @@ -82,7 +82,7 @@ - KR/EN 문서(README, USER_MANUAL, CHANGELOG) 동기화 - 패키지 버전을 1.3.3으로 업데이트 -## v2.1.1-beta(v1.3.1) - 파일명 변수 및 DATE 개선 (2025-10-30) +## v2.1.1(v1.3.1) - 파일명 변수 및 DATE 개선 (2025-10-30) ### ✨ 변경 사항 - 출력 파일명 변수 기능 강화 @@ -105,7 +105,7 @@ - USER_MANUAL/USER_MANUAL_KR: 파일명 변수(`DB_NAME`, DATE), 소문자 토큰, 로컬 시간 동작 설명 추가 - CHANGELOG/CHANGELOG_KR: v1.3.1 항목 추가 -## v2.1.0-beta(v1.3.0) - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) +## v2.1.0(v1.3.0) - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) ### ✨ 변경 사항 - 출력 확장자에 따른 라우팅 @@ -132,7 +132,7 @@ - USER_MANUAL/USER_MANUAL_KR: 라우팅, 디렉토리/파일명 규칙, 기본값 섹션 추가 - CHANGELOG/CHANGELOG_KR: v1.3.0 항목 추가 -## v2.0.11-beta(v1.2.11) - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) +## v2.0.11(v1.2.11) - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) ### ✨ 변경 사항 - 시트명 길이 31자 초과 시 이제 검증에서 오류가 아닌 경고로 처리합니다. @@ -150,7 +150,7 @@ - README/README_KR: v1.2.11 하이라이트 및 변경점 반영 - CHANGELOG/CHANGELOG_KR: v1.2.11 항목 추가 -## v2.0.10-beta(v1.2.10) - 비대화식 CLI 및 문서 업데이트 (2025-10-29) +## v2.0.10(v1.2.10) - 비대화식 CLI 및 문서 업데이트 (2025-10-29) ### ✨ 새로운 기능 @@ -163,7 +163,7 @@ - README.md / README_KR.md: "비대화식 CLI" 사용법과 예시 추가 -## v2.0.0-beta - 다중 데이터베이스 지원 (2025-10-22) +## v2.0.0 - 다중 데이터베이스 지원 (2025-10-22) ### ✨ 새로운 기능 - **다중 데이터베이스 지원**: MSSQL 외 다양한 데이터베이스 타입 지원 diff --git a/README.md b/README.md index 7f137a4..93641c5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A Node.js-based tool for generating Excel files from SQL query results. -## v2.1.5-beta(v1.3.5) Highlights +## v2.1.5 Highlights - DynamicVar DB routing - `dynamicVar` now supports `db` (alias of `database`) attribute in XML. @@ -10,7 +10,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - XML validation update - `queryDef` now allows `db` attribute in XML schema validation. Note: current execution still uses sheet-level `db` or global default; `queryDef.db` is for future use/documentation. -## v2.1.4-beta(v1.3.4) Highlights +## v2.1.4(v1.3.4) Highlights - Adapter-level DB connection test queries - Added `getTestQuery()` to all DB adapters @@ -20,7 +20,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` - Aligns with sample data and improves parity with MSSQL schema -## v2.1.3-beta(v1.3.3) Highlights +## v2.1.3(v1.3.3) Highlights - Documentation synchronization (KR/EN) and minor updates - Package version updated to 1.3.3 @@ -29,7 +29,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet -- 🗄️ **Multi-Database Support (v1.3.0)**: Support for MSSQL, MySQL, and MariaDB with unified interface +- 🗄️ **Multi-Database Support (v2.0.0+)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -62,7 +62,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Dev: `npm run list-dbs` - EXE: `sql2excel.exe list-dbs` -## v2.1.2-beta(v1.3.2) Highlights +## v2.1.2(v1.3.2) Highlights - Per-sheet export directory naming simplified - Directory is now `` (extension suffix removed) @@ -74,7 +74,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Record separators remain CRLF; headers included - Date values are serialized as `yyyy-MM-dd HH:mm:ss` (24-hour) in CSV/TXT and SQL literals -## v2.1.1-beta(v1.3.1) Highlights +## v2.1.1(v1.3.1) Highlights - Filename variables in output path - Support `${DB_NAME}` (current DB key), custom syntax `$(DB_NAME}` normalized automatically @@ -82,7 +82,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Lowercase date tokens supported: `yyyy, yy, dd, d, hh, h, sss` - Removed auto `_yyyymmddhhmmss` suffix; control naming via DATE variables -## v2.1.0-beta(v1.3.0) Highlights +## v2.1.0(v1.3.0) Highlights - **Per-sheet export routing by extension** - `.xlsx` / `.xls` → Generate a single Excel workbook (existing behavior) diff --git a/README_KR.md b/README_KR.md index c5e2171..251ea1f 100644 --- a/README_KR.md +++ b/README_KR.md @@ -2,7 +2,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니다. -## v2.1.5-beta(v1.3.5) 하이라이트 +## v2.1.5 하이라이트 - 동적 변수 DB 라우팅 - XML의 `dynamicVar`에서 `db`(= `database` 별칭) 속성 지원. @@ -10,7 +10,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - XML 검증 업데이트 - XML 스키마 검증에서 `queryDef`의 `db` 속성을 허용. 주의: 현재 실행 DB는 시트의 `db` 또는 전역 기본 DB가 사용되며, `queryDef.db`는 향후 문서/확장용. -## v2.1.4-beta(v1.3.4) 하이라이트 +## v2.1.4(v1.3.4) 하이라이트 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -20,7 +20,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -## v2.1.3-beta(v1.3.3) 하이라이트 +## v2.1.3(v1.3.3) 하이라이트 - 문서 동기화(KR/EN) 및 소규모 정리 - 패키지 버전을 1.3.3으로 업데이트 @@ -29,7 +29,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 -- 🗄️ **다중 데이터베이스 지원 (v1.3.0)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 +- 🗄️ **다중 데이터베이스 지원 (v2.0.0+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -62,7 +62,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 개발: `npm run list-dbs` - EXE: `sql2excel.exe list-dbs` -## v2.1.2-beta(v1.3.2) 하이라이트 +## v2.1.2(v1.3.2) 하이라이트 - 시트별 내보내기 디렉토리 명명 단순화 - 디렉토리는 이제 `<출력파일베이스>` (확장자 접미사 제거) @@ -74,7 +74,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 레코드 구분 개행은 CRLF 유지, 헤더 포함 - 날짜 값은 CSV/TXT 및 SQL 리터럴에서 `yyyy-MM-dd HH:mm:ss`(24시간) 형식으로 직렬화 -## v2.1.1-beta(v1.3.1) 하이라이트 +## v2.1.1(v1.3.1) 하이라이트 - 출력 경로에서 파일명 변수 지원 강화 - `${DB_NAME}` 지원 (현재 기본 DB 키). 커스텀 문법 `$(DB_NAME}`는 자동으로 `${DB_NAME}`로 정규화 @@ -82,7 +82,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 소문자 날짜 토큰 지원: `yyyy, yy, dd, d, hh, h, sss` - 자동 `_yyyymmddhhmmss` 접미사 제거 → DATE 변수로 직접 제어 -## v2.1.0-beta(v1.3.0) 하이라이트 +## v2.1.0(v1.3.0) 하이라이트 - **확장자 기반 시트별 내보내기 라우팅** - `.xlsx` / `.xls` → 단일 엑셀 통합문서 생성 (기존 동작) diff --git a/USER_MANUAL.md b/USER_MANUAL.md index 5ed24a5..aa5b2c8 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -19,7 +19,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL query results with advanced styling, template support, and standalone executable distribution. -### What's New (v2.1.5-beta, v1.3.5) +### What's New (v2.1.5, v1.3.5) - DynamicVar DB routing - XML `dynamicVar` supports `db` (alias of `database`) attribute @@ -27,7 +27,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - XML validation update - `queryDef` accepts `db` in schema validation (execution DB is still determined by sheet `db` or global default) -### What's New (v2.1.4-beta, v1.3.4) +### What's New (v2.1.4, v1.3.4) - Adapter-level DB connection test queries - Added `getTestQuery()` to all DB adapters @@ -37,7 +37,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` - Aligns with sample data and improves parity with MSSQL schema -### What's New (v2.1.3-beta, v1.3.3) +### What's New (v2.1.3, v1.3.3) - Added `exceptColumns` sheet option (XML/JSON) to exclude specific columns from outputs - Documentation synchronization across KR/EN @@ -47,7 +47,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet -- 🗄️ **Multi-Database Support (v1.3.0)**: Support for MSSQL, MySQL, and MariaDB with unified interface +- 🗄️ **Multi-Database Support (v2.0.0+)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -67,7 +67,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 📋 **SQL Query Formatting**: Preserve original SQL formatting with line breaks in Table of Contents - 🔧 **Input Validation**: Automatic whitespace trimming for file path inputs -### What's New (v2.1.2-beta, v1.3.2) +### What's New (v2.1.2, v1.3.2) - Per-sheet export routing by extension - `.xlsx` / `.xls` → Generate a single Excel workbook (existing behavior) diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index bf172ac..521bd34 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -19,7 +19,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 기능을 갖춘 SQL 쿼리 결과로 엑셀 파일을 생성하는 강력한 Node.js 기반 도구입니다. -### v2.1.5-beta(v1.3.5) 주요 변경 +### v2.1.5 주요 변경 - 동적 변수 DB 라우팅 - XML `dynamicVar`에서 `db` 속성 지원 (`database`의 별칭) @@ -27,7 +27,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - XML 검증 업데이트 - XML 스키마 검증에서 `queryDef`의 `db` 속성 허용 (실행 DB는 여전히 시트 `db` 또는 전역 기본 DB로 결정) -### v2.1.4-beta(v1.3.4) 주요 변경 +### v2.1.4(v1.3.4) 주요 변경 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -37,7 +37,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -### v2.1.3-beta(v1.3.3) 주요 변경 +### v2.1.3(v1.3.3) 주요 변경 - 시트에서 특정 컬럼 제외를 위한 `exceptColumns` 속성 추가 (XML/JSON) @@ -45,7 +45,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 -- 🗄️ **다중 데이터베이스 지원 (v1.3.0)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 +- 🗄️ **다중 데이터베이스 지원 (v2.0.0+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -65,7 +65,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 📋 **SQL 쿼리 포맷팅**: 목차에서 줄바꿈을 포함한 원본 SQL 포맷 유지 - 🔧 **입력 유효성 검증**: 파일 경로 입력에 대한 자동 공백 제거 -### v2.1.2-beta(v1.3.2) What's New +### v2.1.2(v1.3.2) What's New - 확장자 기반 시트별 내보내기 라우팅(유지) - `.xlsx` / `.xls` → 단일 엑셀 통합문서 생성 (기존 동작) From 41a43cbc9ca98ef083c2e4223aec9183b8303de5 Mon Sep 17 00:00:00 2001 From: mrjung72 Date: Sat, 15 Nov 2025 19:37:05 +0900 Subject: [PATCH 25/25] Updated version history --- CHANGELOG.md | 12 ++++++------ CHANGELOG_KR.md | 14 +++++++------- README.md | 10 +++++----- README_KR.md | 10 +++++----- USER_MANUAL.md | 10 +++++----- USER_MANUAL_KR.md | 14 +++++++------- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 995b091..afaa8bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,7 @@ - USER_MANUAL/USER_MANUAL_KR: Documented dynamicVar attributes and per-variable DB routing - CHANGELOG/CHANGELOG_KR: Added v2.1.5 entries -## v2.1.4(v1.3.4) - DB Adapter Test Query & Schema Alignment (2025-11-08) +## v2.1.4 - DB Adapter Test Query & Schema Alignment (2025-11-08) ### ✨ New/Changed - Adapter-level connection test SQL @@ -102,7 +102,7 @@ - USER_MANUAL/USER_MANUAL_KR: Updated per-sheet export section to reflect new directory naming and formatting rules - CHANGELOG/CHANGELOG_KR: Added v1.3.2 entry -## v2.1.1(v1.3.1) - Filename Variables and DATE Fixes (2025-10-30) +## v2.1.1-beta (v1.3.1) - Filename Variables and DATE Fixes (2025-10-30) ### ✨ New/Changed - Output filename variable enhancements @@ -125,7 +125,7 @@ - USER_MANUAL/USER_MANUAL_KR: Documented filename variables (`DB_NAME`, DATE), lowercase tokens, and local-time behavior - CHANGELOG/CHANGELOG_KR: Added v1.3.1 entry -## v2.1.0(v1.3.0) - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) +## v2.1.0-beta (v1.3.0) - Per-sheet Export for CSV/TXT and Routing Rules (2025-10-29) ### ✨ New/Changed - Export routing based on output extension @@ -152,7 +152,7 @@ - USER_MANUAL/USER_MANUAL_KR: Added section describing routing, directory/filename rules, and defaults - CHANGELOG/CHANGELOG_KR: Added v1.3.0 entry -## v2.0.11(v1.2.11) - TOC Original Name & Sheet Name Length Warning (2025-10-29) +## v2.0.2-beta (v1.2.11) - TOC Original Name & Sheet Name Length Warning (2025-10-29) ### ✨ New/Changed - Sheet name length > 31 characters is now treated as a warning during validation (no failure) @@ -170,7 +170,7 @@ - README/README_KR: Updated highlights to v1.2.11, described changes - CHANGELOG: Added v1.2.11 entry -## v2.0.10(v1.2.10) - Non-interactive CLI & Docs (2025-10-29) +## v2.0.1-beta (v1.2.10) - Non-interactive CLI & Docs (2025-10-29) ### ✨ New Features @@ -183,7 +183,7 @@ - README.md / README_KR.md: Added "Non-interactive CLI" usage and examples - Updated highlights to v1.2.10 -## v2.0.0 - Multi-Database Support (2025-10-22) +## v2.0.0-beta - Multi-Database Support (2025-10-22) ### ✨ New Features - **Multi-Database Support**: Support for multiple database types beyond MSSQL diff --git a/CHANGELOG_KR.md b/CHANGELOG_KR.md index e385f95..1a932ce 100644 --- a/CHANGELOG_KR.md +++ b/CHANGELOG_KR.md @@ -24,7 +24,7 @@ - USER_MANUAL/USER_MANUAL_KR: 동적 변수 속성 및 변수별 DB 라우팅 동작 문서화 - CHANGELOG/CHANGELOG_KR: v2.1.5 항목 추가 -## v2.1.4(v1.3.4) - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) +## v2.1.4 - DB 어댑터 테스트 쿼리 도입 및 스키마 정합성 (2025-11-08) ### ✨ 변경 사항 - 어댑터 단위 연결 테스트 SQL 도입 @@ -59,7 +59,7 @@ ### 📝 비고 - 본 변경으로 샘플 데이터(PostgreSQL)가 각 DB 스키마 적용 시 원활히 적재되도록 정합성이 개선되었습니다. -## v2.1.3(v1.3.3) - 문서 동기화 및 버전 올림 (2025-10-31) +## v2.1.3-beta (v1.3.3) - 문서 동기화 및 버전 올림 (2025-10-31) ### ✨ 변경 사항 - 시트에서 특정 컬럼을 결과에서 제외하는 `exceptColumns` 속성 추가 @@ -82,7 +82,7 @@ - KR/EN 문서(README, USER_MANUAL, CHANGELOG) 동기화 - 패키지 버전을 1.3.3으로 업데이트 -## v2.1.1(v1.3.1) - 파일명 변수 및 DATE 개선 (2025-10-30) +## v2.1.1-beta (v1.3.1) - 파일명 변수 및 DATE 개선 (2025-10-30) ### ✨ 변경 사항 - 출력 파일명 변수 기능 강화 @@ -105,7 +105,7 @@ - USER_MANUAL/USER_MANUAL_KR: 파일명 변수(`DB_NAME`, DATE), 소문자 토큰, 로컬 시간 동작 설명 추가 - CHANGELOG/CHANGELOG_KR: v1.3.1 항목 추가 -## v2.1.0(v1.3.0) - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) +## v2.1.0-beta (v1.3.0) - CSV/TXT 시트별 내보내기 및 라우팅 규칙 (2025-10-29) ### ✨ 변경 사항 - 출력 확장자에 따른 라우팅 @@ -132,7 +132,7 @@ - USER_MANUAL/USER_MANUAL_KR: 라우팅, 디렉토리/파일명 규칙, 기본값 섹션 추가 - CHANGELOG/CHANGELOG_KR: v1.3.0 항목 추가 -## v2.0.11(v1.2.11) - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) +## v2.0.2-beta (v1.2.11) - TOC 원본 시트명 컬럼 및 시트명 길이 경고 (2025-10-29) ### ✨ 변경 사항 - 시트명 길이 31자 초과 시 이제 검증에서 오류가 아닌 경고로 처리합니다. @@ -150,7 +150,7 @@ - README/README_KR: v1.2.11 하이라이트 및 변경점 반영 - CHANGELOG/CHANGELOG_KR: v1.2.11 항목 추가 -## v2.0.10(v1.2.10) - 비대화식 CLI 및 문서 업데이트 (2025-10-29) +## v2.0.1-beta (v1.2.10) - 비대화식 CLI 및 문서 업데이트 (2025-10-29) ### ✨ 새로운 기능 @@ -163,7 +163,7 @@ - README.md / README_KR.md: "비대화식 CLI" 사용법과 예시 추가 -## v2.0.0 - 다중 데이터베이스 지원 (2025-10-22) +## v2.0.0-beta - 다중 데이터베이스 지원 (2025-10-22) ### ✨ 새로운 기능 - **다중 데이터베이스 지원**: MSSQL 외 다양한 데이터베이스 타입 지원 diff --git a/README.md b/README.md index 93641c5..2c40aea 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - XML validation update - `queryDef` now allows `db` attribute in XML schema validation. Note: current execution still uses sheet-level `db` or global default; `queryDef.db` is for future use/documentation. -## v2.1.4(v1.3.4) Highlights +## v2.1.4 Highlights - Adapter-level DB connection test queries - Added `getTestQuery()` to all DB adapters @@ -20,7 +20,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - PostgreSQL/MySQL: added `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` - Aligns with sample data and improves parity with MSSQL schema -## v2.1.3(v1.3.3) Highlights +## v2.1.3-beta (v1.3.3) Highlights - Documentation synchronization (KR/EN) and minor updates - Package version updated to 1.3.3 @@ -29,7 +29,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet -- 🗄️ **Multi-Database Support (v2.0.0+)**: Support for MSSQL, MySQL, and MariaDB with unified interface +- 🗄️ **Multi-Database Support (v2.0.0-beta+)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -74,7 +74,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Record separators remain CRLF; headers included - Date values are serialized as `yyyy-MM-dd HH:mm:ss` (24-hour) in CSV/TXT and SQL literals -## v2.1.1(v1.3.1) Highlights +## v2.1.1-beta (v1.3.1) Highlights - Filename variables in output path - Support `${DB_NAME}` (current DB key), custom syntax `$(DB_NAME}` normalized automatically @@ -82,7 +82,7 @@ A Node.js-based tool for generating Excel files from SQL query results. - Lowercase date tokens supported: `yyyy, yy, dd, d, hh, h, sss` - Removed auto `_yyyymmddhhmmss` suffix; control naming via DATE variables -## v2.1.0(v1.3.0) Highlights +## v2.1.0-beta (v1.3.0) Highlights - **Per-sheet export routing by extension** - `.xlsx` / `.xls` → Generate a single Excel workbook (existing behavior) diff --git a/README_KR.md b/README_KR.md index 251ea1f..16528b2 100644 --- a/README_KR.md +++ b/README_KR.md @@ -10,7 +10,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - XML 검증 업데이트 - XML 스키마 검증에서 `queryDef`의 `db` 속성을 허용. 주의: 현재 실행 DB는 시트의 `db` 또는 전역 기본 DB가 사용되며, `queryDef.db`는 향후 문서/확장용. -## v2.1.4(v1.3.4) 하이라이트 +## v2.1.4 하이라이트 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -20,7 +20,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -## v2.1.3(v1.3.3) 하이라이트 +## v2.1.3-beta (v1.3.3) 하이라이트 - 문서 동기화(KR/EN) 및 소규모 정리 - 패키지 버전을 1.3.3으로 업데이트 @@ -29,7 +29,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 -- 🗄️ **다중 데이터베이스 지원 (v2.0.0+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 +- 🗄️ **다중 데이터베이스 지원 (v2.0.0-beta+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -74,7 +74,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 레코드 구분 개행은 CRLF 유지, 헤더 포함 - 날짜 값은 CSV/TXT 및 SQL 리터럴에서 `yyyy-MM-dd HH:mm:ss`(24시간) 형식으로 직렬화 -## v2.1.1(v1.3.1) 하이라이트 +## v2.1.1-beta (v1.3.1) 하이라이트 - 출력 경로에서 파일명 변수 지원 강화 - `${DB_NAME}` 지원 (현재 기본 DB 키). 커스텀 문법 `$(DB_NAME}`는 자동으로 `${DB_NAME}`로 정규화 @@ -82,7 +82,7 @@ SQL 쿼리 결과를 엑셀 파일로 생성하는 Node.js 기반 도구입니 - 소문자 날짜 토큰 지원: `yyyy, yy, dd, d, hh, h, sss` - 자동 `_yyyymmddhhmmss` 접미사 제거 → DATE 변수로 직접 제어 -## v2.1.0(v1.3.0) 하이라이트 +## v2.1.0-beta (v1.3.0) 하이라이트 - **확장자 기반 시트별 내보내기 라우팅** - `.xlsx` / `.xls` → 단일 엑셀 통합문서 생성 (기존 동작) diff --git a/USER_MANUAL.md b/USER_MANUAL.md index aa5b2c8..c9a0ca8 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -47,7 +47,7 @@ SQL2Excel is a powerful Node.js-based tool for generating Excel files from SQL q - 📊 **Multi-Sheet Support**: Save multiple SQL query results in separate sheets within one Excel file - 🎨 **Template Style System**: Pre-defined Excel styling templates for consistent design with 7 built-in styles - 🔗 **Multiple DB Connections**: Use different database connections for each sheet -- 🗄️ **Multi-Database Support (v2.0.0+)**: Support for MSSQL, MySQL, and MariaDB with unified interface +- 🗄️ **Multi-Database Support (v2.0.0-beta+)**: Support for MSSQL, MySQL, and MariaDB with unified interface - 📝 **Variable System**: Use variables in queries for dynamic query generation - 🔄 **Enhanced Dynamic Variables**: Extract values from database in real-time with advanced processing - 🔄 **Query Reuse**: Define common queries and reuse them across multiple sheets @@ -122,7 +122,7 @@ npm run build ### 3. Database Connection Setup Create `config/dbinfo.json` file: -#### Multi-Database Support (v2.0.0+) +#### Multi-Database Support (v2.0.0-beta+) ```json { "sampleDB": { @@ -459,12 +459,12 @@ sql2excel.exe --mode=help This tool supports multiple databases with unified adapters and flexible routing. - **Supported drivers**: MSSQL (`mssql`), MySQL (`mysql2`), MariaDB (`mysql2`), PostgreSQL (`pg`), SQLite (`better-sqlite3`), Oracle (`oracledb`) -- **Configuration**: Define multiple DB keys in `config/dbinfo.json` with optional `type` (defaults to `mssql`) and connection fields. See examples above and in “Multi-Database Support (v2.0.0+)”. +- **Configuration**: Define multiple DB keys in `config/dbinfo.json` with optional `type` (defaults to `mssql`) and connection fields. See examples above and in “Multi-Database Support (v2.0.0-beta+)”. - **Runtime DB selection precedence (v2.1.5+)** - Default DB key: CLI `--db` > `excel.db` - Per sheet: `sheet.db` overrides default DB - Dynamic variables: `dynamicVar.database` or `dynamicVar.db` overrides default DB -- **Mixed-DB usage**: You can query different DBs within a single export. See “Multi-Database Support (v2.0.0+)” for XML/JSON examples. +- **Mixed-DB usage**: You can query different DBs within a single export. See “Multi-Database Support (v2.0.0-beta+)” for XML/JSON examples. - **Connection test**: Validate connectivity before export with `node src/excel-cli.js list-dbs` (dev) or `sql2excel.exe list-dbs` (EXE). - **Adapter behavior**: Row limiting and functions are adapted per DB (e.g., MSSQL uses TOP, MySQL/MariaDB use LIMIT). @@ -838,7 +838,7 @@ This feature works automatically - no configuration required! ## 🎨 Advanced Features -### 1. Multi-Database Support (v2.0.0+) +### 1. Multi-Database Support (v2.0.0-beta+) SQL2Excel now supports multiple database types with a unified interface: diff --git a/USER_MANUAL_KR.md b/USER_MANUAL_KR.md index 521bd34..5bfe185 100644 --- a/USER_MANUAL_KR.md +++ b/USER_MANUAL_KR.md @@ -27,7 +27,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - XML 검증 업데이트 - XML 스키마 검증에서 `queryDef`의 `db` 속성 허용 (실행 DB는 여전히 시트 `db` 또는 전역 기본 DB로 결정) -### v2.1.4(v1.3.4) 주요 변경 +### v2.1.4 주요 변경 - 어댑터별 DB 연결 테스트 쿼리 도입 - 모든 DB 어댑터에 `getTestQuery()` 추가 @@ -37,7 +37,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - PostgreSQL/MySQL: `SubTotal`, `PaymentMethod`, `PaymentStatus`, `EmployeeID` 추가 - 샘플 데이터와 컬럼 일치, MSSQL 스키마와의 정합성 향상 -### v2.1.3(v1.3.3) 주요 변경 +### v2.1.3-beta (v1.3.3) 주요 변경 - 시트에서 특정 컬럼 제외를 위한 `exceptColumns` 속성 추가 (XML/JSON) @@ -45,7 +45,7 @@ SQL2Excel은 고급 스타일링, 템플릿 지원, 독립 실행 파일 배포 - 📊 **다중 시트 지원**: 하나의 엑셀 파일 내에서 여러 SQL 쿼리 결과를 별도의 시트에 저장 - 🎨 **템플릿 스타일 시스템**: 일관된 디자인을 위한 사전 정의된 엑셀 스타일링 템플릿 (7가지 내장 스타일) - 🔗 **다중 DB 연결**: 각 시트마다 다른 데이터베이스 연결 사용 가능 -- 🗄️ **다중 데이터베이스 지원 (v2.0.0+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 +- 🗄️ **다중 데이터베이스 지원 (v2.0.0-beta+)**: MSSQL, MySQL, MariaDB를 통합 인터페이스로 지원 - 📝 **변수 시스템**: 동적 쿼리 생성을 위한 변수 사용 - 🔄 **향상된 동적 변수**: 실시간으로 데이터베이스에서 값을 추출하여 고급 처리 - 🔄 **쿼리 재사용**: 공통 쿼리를 정의하고 여러 시트에서 재사용 @@ -121,7 +121,7 @@ npm run build ### 3. 데이터베이스 연결 설정 `config/dbinfo.json` 파일을 생성하세요: -#### 다중 데이터베이스 지원 (v2.0.0+) +#### 다중 데이터베이스 지원 (v2.0.0-beta+) ```json { "sampleDB": { @@ -471,12 +471,12 @@ sql2excel.exe --mode=help 통합 어댑터와 유연한 라우팅으로 여러 데이터베이스를 지원합니다. - **지원 드라이버**: MSSQL(`mssql`), MySQL(`mysql2`), MariaDB(`mysql2`), PostgreSQL(`pg`), SQLite(`better-sqlite3`), Oracle(`oracledb`) -- **설정**: `config/dbinfo.json`에 다수의 DB 키를 정의하고 `type`(미지정 시 `mssql`)과 접속 정보를 설정하세요. 상세 예시는 위 “다중 데이터베이스 지원 (v2.0.0+)” 섹션 참고. +- **설정**: `config/dbinfo.json`에 다수의 DB 키를 정의하고 `type`(미지정 시 `mssql`)과 접속 정보를 설정하세요. 상세 예시는 위 “다중 데이터베이스 지원 (v2.0.0-beta+)” 섹션 참고. - **런타임 DB 선택 우선순위 (v2.1.5+) - 기본 DB 키: CLI `--db` > `excel.db` - 시트별: `sheet.db`가 기본 DB를 오버라이드 - 동적 변수: `dynamicVar.database` 또는 `dynamicVar.db`가 기본 DB를 오버라이드 -- **혼합 사용**: 하나의 내보내기에서 서로 다른 DB를 동시에 사용할 수 있습니다. XML/JSON 예시는 “다중 데이터베이스 지원 (v2.0.0+)” 섹션을 참고하세요. +- **혼합 사용**: 하나의 내보내기에서 서로 다른 DB를 동시에 사용할 수 있습니다. XML/JSON 예시는 “다중 데이터베이스 지원 (v2.0.0-beta+)” 섹션을 참고하세요. - **연결 테스트**: 내보내기 전 `node src/excel-cli.js list-dbs`(개발) 또는 `sql2excel.exe list-dbs`(EXE)로 확인하세요. - **어댑터 동작**: 행 제한과 함수가 DB별로 자동 조정됩니다 (예: MSSQL=TOP, MySQL/MariaDB=LIMIT). @@ -845,7 +845,7 @@ SQL2Excel은 생성된 각 엑셀 시트에 자동으로 생성 타임스탬프 ## 🎨 고급 기능 -### 1. 다중 데이터베이스 지원 (v2.0.0+) +### 1. 다중 데이터베이스 지원 (v2.0.0-beta+) SQL2Excel은 이제 통합 인터페이스로 여러 데이터베이스 타입을 지원합니다: