Oracle函数大全九:NLS_UPPER函数

本文介绍了Oracle的NLS_UPPER函数,用于将字符串转为大写,支持自定义排序规则。函数适用于处理具有特殊大小写规则的语言,与UPPER函数相比,能适应不同语言环境。提供了SQL示例和注意事项。

Oracle函数NLS_UPPER用于将字符串中的所有字符转换为大写。它允许你指定在转换过程中使用的排序规则,这在处理具有特殊大小写规则的语言时非常有用。

函数的基本语法如下:


sql复制代码

NLS_UPPER(string [, 'nlsparam' ])

参数说明:

  • string:这是必需的参数,代表要转换为大写的字符串。string可以是CHAR, VARCHAR2, NCHAR, NVARCHAR2, CLOB, 或NCLOB类型的数据。
  • 'nlsparam':这是一个可选参数,用于指定转换时使用的排序规则。它的形式通常是'NLS_SORT = sort_method',其中sort_method是特定的排序方法。如果省略此参数,NLS_UPPER函数将使用默认的排序规则。

返回值:

NLS_UPPER函数返回输入字符串的大写形式。如果输入字符串为NULL,则返回NULL。

示例:


sql复制代码

SELECT NLS_UPPER('hello world') FROM DUAL;

上述查询将返回'HELLO WORLD',因为所有字符都被转换为了大写。

在处理具有特殊大小写规则的语言时,使用NLS_UPPER函数结合适当的nlsparam参数可以确保正确的转换。例如,在某些语言环境中,大写形式可能与标准ASCII字符集的大写形式不同。

请注意,与UPPER函数类似,NLS_UPPER函数也直接作用于输入字符串的字符,而不考虑任何可能的字符编码或语言环境特定的大小写规则。如果你需要处理更复杂的字符转换,可能需要使用其他函数或方法。

总的来说,NLS_UPPER函数提供了一种灵活的方式来将字符串转换为大写,并且可以根据需要调整排序规则来适应不同的语言环境。

一个Python 作为Sqlite 数据传输同步到Oracle ,源码 import sqlite3 import oracledb from datetime import datetime, timedelta import logging import re # 日志配置 logging.basicConfig( filename='db_sync_debug.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', encoding='utf-8' ) # 增强的日期格式正则表达式 DATE_REGEX = re.compile( r'^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?$' ) # 主键映射表 TABLE_PRIMARY_KEYS = { "OEE_AvaiableTime": "OEE_AvaiableTimeId", "OEE_CycleTime": "OEE_CycleTimeId", "OEE_CycleTime_Config": "OEE_CycleTimeConfigId", "OEE_LineReport": "OEE_LineReportId", "OEE_PerformanceComment": "OEE_PerformanceCommentId", "OEE_ProductStatus": "OEE_ProductStatusId", "OEE_Quality": "OEE_QualityId", "OEE_ShiftPlan_Config": "OEE_ShiftPlanConfigId", "OEE_ShiftWorkTime": "OEE_ShiftWorkTimeId", "OEE_Target_Config": "OEE_TargetConfigId" } # Oracle 关键字列表(扩展) ORACLE_KEYWORDS = { 'ACCESS', 'ADD', 'ALL', 'ALTER', 'AND', 'ANY', 'AS', 'ASC', 'AUDIT', 'BETWEEN', 'BY', 'CHAR', 'CHECK', 'CLUSTER', 'COLUMN', 'COMMENT', 'COMPRESS', 'CONNECT', 'CREATE', 'CURRENT', 'DATE', 'DECIMAL', 'DEFAULT', 'DELETE', 'DESC', 'DISTINCT', 'DROP', 'ELSE', 'EXCLUSIVE', 'EXISTS', 'FILE', 'FLOAT', 'FOR', 'FROM', 'GRANT', 'GROUP', 'HAVING', 'IDENTIFIED', 'IMMEDIATE', 'IN', 'INCREMENT', 'INDEX', 'INITIAL', 'INSERT', 'INTEGER', 'INTERSECT', 'INTO', 'IS', 'LEVEL', 'LIKE', 'LOCK', 'LONG', 'MAXEXTENTS', 'MINUS', 'MLSLABEL', 'MODE', 'MODIFY', 'NOAUDIT', 'NOCOMPRESS', 'NOT', 'NOWAIT', 'NULL', 'NUMBER', 'OF', 'OFFLINE', 'ON', 'ONLINE', 'OPTION', 'OR', 'ORDER', 'PCTFREE', 'PRIOR', 'PRIVILEGES', 'PUBLIC', 'RAW', 'RENAME', 'RESOURCE', 'REVOKE', 'ROW', 'ROWID', 'ROWNUM', 'ROWS', 'SELECT', 'SESSION', 'SET', 'SHARE', 'SIZE', 'SMALLINT', 'START', 'SUCCESSFUL', 'SYNONYM', 'SYSDATE', 'TABLE', 'THEN', 'TO', 'TRIGGER', 'UID', 'UNION', 'UNIQUE', 'UPDATE', 'USER', 'VALIDATE', 'VALUES', 'VARCHAR', 'VARCHAR2', 'VIEW', 'WHENEVER', 'WHERE', 'WITH', 'TYPE', 'MI', 'SS' # 添加了额外的关键字 } def generate_bind_name(col_name, is_date=False): """生成安全的绑定变量名""" base_name = col_name.lower().replace(' ', '_') if is_date: base_name = f"{base_name}_dt" if base_name.upper() in ORACLE_KEYWORDS: base_name = f"_{base_name}_" if re.search(r'[^a-z0-9_]', base_name): base_name = f"_{base_name}_" return base_name def validate_bind_variables(sql, params): """ 改进的绑定变量验证: 1. 修复未初始化变量问题 2. 增强字符串字面值处理 """ bind_names = set() in_string = False current_name = "" collecting = False # 关键初始化 # 解析SQL查找所有绑定变量占位符 for char in sql: # 处理字符串字面值开始/结束 if char == "'": in_string = not in_string continue # 只在非字符串区域处理 if not in_string: # 遇到冒号开始收集 if char == ':': collecting = True continue # 收集有效绑定变量名字符 if collecting and (char.isalnum() or char == '_'): current_name += char continue # 结束当前绑定变量名收集 if collecting and current_name: bind_names.add(current_name) current_name = "" collecting = False # 处理最后一个绑定变量(如果存在) if collecting and current_name: bind_names.add(current_name) # 验证参数匹配 param_keys = set(params.keys()) missing = bind_names - param_keys extra = param_keys - bind_names if missing: logging.warning(f"SQL中有但参数字典中缺失的绑定变量: {missing}") return False if extra: logging.warning(f"参数字典中有但SQL中未使用的绑定变量: {extra}") return False return True def debug_log_sql(sql, params): """安全的SQL日志记录,避免错误替换字符串字面值""" logging.debug("SQL语句:") logging.debug(sql) logging.debug("绑定参数:") safe_params = {} for k, v in params.items(): if isinstance(v, str) and len(v) > 50: safe_params[k] = f"[{v[:20]}...]" else: safe_params[k] = v logging.debug(safe_params) def generate_insert_sql(table, columns, oracle_columns, row_data): """更健壮的INSERT SQL生成器""" cols = [] values = [] bind_params = {} for col in columns: col_upper = col.upper() if col_upper not in oracle_columns: continue col_type = oracle_columns[col_upper] value = row_data[col] # 生成安全的绑定变量名 is_date_field = "DATE" in col_type or "TIMESTAMP" in col_type bind_name = generate_bind_name(col, is_date_field) # 处理日期字段 if is_date_field: values.append(f"TO_DATE(:{bind_name}, 'YYYY-MM-DD HH24:MI:SS')") bind_params[bind_name] = value # 处理NULL值 elif value is None: values.append("NULL") else: values.append(f":{bind_name}") bind_params[bind_name] = value cols.append(f'"{col_upper}"') cols_str = ", ".join(cols) values_str = ", ".join(values) sql = f"INSERT INTO {table} ({cols_str}) VALUES ({values_str})" # 验证绑定变量匹配性 if not validate_bind_variables(sql, bind_params): logging.error("生成的SQL绑定变量验证失败!") return sql, bind_params def sync_sqlite_to_oracle(sqlite_db, oracle_dsn, username, password, tables, test_mode): """最终优化的数据库同步方案""" # 计算时间范围 - 支持测试模式 if test_mode: # 指定固定测试时间范围 start_time = '2025-10-05 08:20:00' end_time = '2025-10-06 08:20:00' else: # 动态计算时间范围 now = datetime.datetime.now() start_time = (now - datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S') end_time = now.strftime('%Y-%m-%d %H:%M:%S') logging.info(f"同步时间范围: {start_time} 到 {end_time}") try: sqlite_conn = sqlite3.connect(sqlite_db) sqlite_cursor = sqlite_conn.cursor() oracle_conn = oracledb.connect( user=username, password=password, dsn=oracle_dsn ) oracle_cursor = oracle_conn.cursor() # 设置Oracle会话日期格式 oracle_cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'") oracle_conn.commit() for table in tables: primary_key = TABLE_PRIMARY_KEYS.get(table) if not primary_key: logging.error(f"未定义主键的表: {table}") continue logging.info(f"开始同步表: {table}, 主键: {primary_key}") # 获取SQLite表结构 sqlite_cursor.execute(f"PRAGMA table_info({table})") columns = [col[1] for col in sqlite_cursor.fetchall()] # 获取Oracle列信息 oracle_cursor.execute(""" SELECT column_name, data_type FROM user_tab_columns WHERE table_name = UPPER(:table_name) """, table_name=table) oracle_columns = {col[0].upper(): col[1].upper() for col in oracle_cursor.fetchall()} # 查询变更记录 sqlite_cursor.execute(f""" SELECT * FROM {table} WHERE UpdateAt BETWEEN ? AND ? """, (start_time, end_time)) rows = sqlite_cursor.fetchall() for row in rows: row_dict = dict(zip(columns, row)) oracle_compatible_data = {} # 格式化数据为Oracle兼容格式 for col_name, value in row_dict.items(): col_upper = col_name.upper() if col_upper in oracle_columns: col_type = oracle_columns[col_upper] # 处理日期字段 if "DATE" in col_type or "TIMESTAMP" in col_type: formatted = format_date_value(value) oracle_compatible_data[col_name] = formatted if formatted else value else: oracle_compatible_data[col_name] = value else: oracle_compatible_data[col_name] = value # 检查记录是否存在 pk_value = oracle_compatible_data[primary_key] oracle_cursor.execute(f""" SELECT COUNT(*) FROM {table} WHERE "{primary_key.upper()}" = :pk_value """, pk_value=pk_value) if oracle_cursor.fetchone()[0] > 0: # 更新记录 update_sql, update_params = generate_update_sql( table, columns, primary_key, oracle_columns, oracle_compatible_data ) sql_to_execute = update_sql params_to_execute = update_params else: # 插入记录 insert_sql, insert_params = generate_insert_sql( table, columns, oracle_columns, oracle_compatible_data ) sql_to_execute = insert_sql params_to_execute = insert_params # 执行SQL try: debug_log_sql(sql_to_execute, params_to_execute) oracle_cursor.execute(sql_to_execute, params_to_execute) except oracledb.DatabaseError as e: handle_oracle_error(e, sql_to_execute, params_to_execute) raise oracle_conn.commit() logging.info(f"{table} 同步完成") logging.info("所有表同步成功") except Exception as e: logging.error(f"同步失败: {str(e)}", exc_info=True) if 'oracle_conn' in locals(): oracle_conn.rollback() finally: if 'sqlite_conn' in locals(): sqlite_conn.close() if 'oracle_conn' in locals(): oracle_conn.close() def format_date_value(value): """格式化日期值为Oracle兼容格式""" if isinstance(value, str): match = DATE_REGEX.match(value) if match: groups = match.groups() return f"{groups[0]}-{groups[1]}-{groups[2]} {groups[3]}:{groups[4]}:{groups[5]}" elif isinstance(value, datetime): return value.strftime('%Y-%m-%d %H:%M:%S') return value def handle_oracle_error(error, sql, params): """详细的Oracle错误处理""" try: error_obj = error.args[0] logging.error(f"Oracle错误: {error_obj.message} (代码: {error_obj.code})") except: logging.error(f"数据库错误: {str(error)}") logging.error(f"问题SQL: {sql}") logging.error(f"绑定参数: {params}") # 提供具体解决方案 if "ORA-01745" in str(error): logging.error("解决方案: 检查绑定变量名是否包含无效字符或Oracle关键字") elif "DPY-4008" in str(error): logging.error("解决方案: 确保所有绑定变量在SQL和参数字典中精确匹配") logging.error("检查步骤: 使用validate_bind_variables函数验证一致性") def generate_update_sql(table, columns, primary_key, oracle_columns, row_data): """更健壮的UPDATE SQL生成器""" set_clauses = [] bind_params = {} for col in columns: if col == primary_key: continue col_upper = col.upper() if col_upper not in oracle_columns: continue col_type = oracle_columns[col_upper] value = row_data[col] # 生成安全的绑定变量名 is_date_field = "DATE" in col_type or "TIMESTAMP" in col_type bind_name = generate_bind_name(col, is_date_field) # 处理日期字段 if is_date_field: set_clauses.append(f'"{col_upper}" = TO_DATE(:{bind_name}, \'YYYY-MM-DD HH24:MI:SS\')') bind_params[bind_name] = value # 处理NULL值 elif value is None: set_clauses.append(f'"{col_upper}" = NULL') else: set_clauses.append(f'"{col_upper}" = :{bind_name}') bind_params[bind_name] = value # 添加主键条件 pk_bind_name = generate_bind_name(primary_key) bind_params[pk_bind_name] = row_data[primary_key] set_clause = ", ".join(set_clauses) sql = f"UPDATE {table} SET {set_clause} WHERE \"{primary_key.upper()}\" = :{pk_bind_name}" # 验证绑定变量匹配性 if not validate_bind_variables(sql, bind_params): logging.error("生成的SQL绑定变量验证失败!") return sql, bind_params if __name__ == "__main__": # 配置参数 SQLITE_DB = "D:\\IISwebOEE\\App_Data\\webFrameworkEF6.db" ORACLE_DSN = "at3-pacc-f2db.zf-world.com/AT3PACC2" USERNAME = "acc_oee2" PASSWORD = "accZF_2025" TABLES = [ "OEE_AvaiableTime", "OEE_CycleTime", "OEE_LineReport", "OEE_PerformanceComment", "OEE_ProductStatus", "OEE_Quality", "OEE_ShiftPlan_Config", "OEE_ShiftWorkTime", "OEE_Target_Config", "OEE_CycleTime_Config" ] # 启用测试模式使用固定时间范围 sync_sqlite_to_oracle( SQLITE_DB, ORACLE_DSN, USERNAME, PASSWORD, TABLES, test_mode=True # 启用测试模式 ) 目前是遇到问题 2025-11-07 09:42:42,481 - INFO - 开始同步表: OEE_AvaiableTime, 主键: OEE_AvaiableTimeId 2025-11-07 09:42:47,025 - DEBUG - SQL语句: 2025-11-07 09:42:47,025 - DEBUG - INSERT INTO OEE_AvaiableTime ("OEE_AVAIABLETIMEID", "STARTTIME", "ENDTIME", "DURATION", "TYPE", "OP", "PARTNO", "LOSSREASON", "COMMENT", "SHIFTWORKTIMEID", "CREATEAT", "UPDATEAT", "BYUSER") VALUES (:oee_avaiabletimeid, :starttime, :endtime, :duration, :_type_, NULL, NULL, NULL, :_comment_, :shiftworktimeid, TO_DATE(:createat_dt, 'YYYY-MM-DD HH24:MI:SS'), TO_DATE(:updateat_dt, 'YYYY-MM-DD HH24:MI:SS'), :byuser) 2025-11-07 09:42:47,025 - DEBUG - 绑定参数: 2025-11-07 09:42:47,025 - DEBUG - {'oee_avaiabletimeid': '6b245d77-56ae-429e-809b-f8b71ddf19fb', 'starttime': '176', 'endtime': '179', 'duration': 15, '_type_': '13', '_comment_': '2人,22小时', 'shiftworktimeid': 'd3369a2c-5097-4654-b63c-4a7812b6e54b', 'createat_dt': '2025-10-04 12:37:08', 'updateat_dt': '2025-10-05 18:51:51', 'byuser': 'AD'} 2025-11-07 09:42:47,026 - ERROR - Oracle错误: DPY-4008: no bind placeholder named ":_type_" was found in the SQL text (代码: 0) 2025-11-07 09:42:47,026 - ERROR - 问题SQL: INSERT INTO OEE_AvaiableTime ("OEE_AVAIABLETIMEID", "STARTTIME", "ENDTIME", "DURATION", "TYPE", "OP", "PARTNO", "LOSSREASON", "COMMENT", "SHIFTWORKTIMEID", "CREATEAT", "UPDATEAT", "BYUSER") VALUES (:oee_avaiabletimeid, :starttime, :endtime, :duration, :_type_, NULL, NULL, NULL, :_comment_, :shiftworktimeid, TO_DATE(:createat_dt, 'YYYY-MM-DD HH24:MI:SS'), TO_DATE(:updateat_dt, 'YYYY-MM-DD HH24:MI:SS'), :byuser) 2025-11-07 09:42:47,026 - ERROR - 绑定参数: {'oee_avaiabletimeid': '6b245d77-56ae-429e-809b-f8b71ddf19fb', 'starttime': '176', 'endtime': '179', 'duration': 15, '_type_': '13', '_comment_': '2人,22小时', 'shiftworktimeid': 'd3369a2c-5097-4654-b63c-4a7812b6e54b', 'createat_dt': '2025-10-04 12:37:08', 'updateat_dt': '2025-10-05 18:51:51', 'byuser': 'AD'} 2025-11-07 09:42:47,026 - ERROR - 解决方案: 确保所有绑定变量在SQL和参数字典中精确匹配 2025-11-07 09:42:47,027 - ERROR - 检查步骤: 使用validate_bind_variables函数验证一致性 2025-11-07 09:42:47,027 - ERROR - 同步失败: DPY-4008: no bind placeholder named ":_type_" was found in the SQL text Traceback (most recent call last): File "C:\UserData\Python\SyncSqlitedb\sync_service.py", line 275, in sync_sqlite_to_oracle oracle_cursor.execute(sql_to_execute, params_to_execute) ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\guc3\AppData\Roaming\Python\Python313\site-packages\oracledb\cursor.py", line 708, in execute impl.execute(self) ~~~~~~~~~~~~^^^^^^ File "src/oracledb/impl/thin/cursor.pyx", line 275, in oracledb.thin_impl.ThinCursorImpl.execute File "src/oracledb/impl/thin/cursor.pyx", line 182, in oracledb.thin_impl.BaseThinCursorImpl._preprocess_execute File "src/oracledb/impl/base/cursor.pyx", line 351, in oracledb.base_impl.BaseCursorImpl._perform_binds File "src/oracledb/impl/thin/var.pyx", line 95, in oracledb.thin_impl.ThinVarImpl._bind File "C:\Users\guc3\AppData\Roaming\Python\Python313\site-packages\oracledb\errors.py", line 199, in _raise_err raise error.exc_type(error) from cause oracledb.exceptions.DatabaseError: DPY-4008: no bind placeholder named ":_type_" was found in the SQL text 请帮忙解决
最新发布
11-08
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值