注册
环境函数 SYS_CONTEXT 在 DM8 与 Oracle 中的差异
技术分享/ 文章详情 /

环境函数 SYS_CONTEXT 在 DM8 与 Oracle 中的差异

codePanda 2025/10/17 72 1 0

在 Oracle 数据库中,SYS_CONTEXT(namespace, parameter) 函数用于返回当前数据库会话的环境信息,例如用户、主机、实例、语言、会话 ID 等。这一机制在数据库审计、安全控制、运维脚本中非常实用。而在国产数据库达梦(DM8)中,虽然官方文档中并未明确介绍该函数,但经实测发现该函数依然可用,且与 Oracle 高度兼容。

基本语法:

SELECT SYS_CONTEXT('USERENV', '<参数名>') FROM dual;

DM8 版本

DM官网没有找到关于SYS_CONTEXT函数的介绍,在v$ifun函数定义中是能找到的,根据这一周的学习情况来看,很多Oracle上的SQL在DM上依旧通用,下面就用ORACLE常用的 userenv namespace 在DM8上 测试一下

版本:DM Database Server 64 V8–03134284368-20250430-272000-20149 Pack1

dmdba@DAMENG:5236 SQL> select top 1 banner || id_code from v$version; BANNER||ID_CODE ----------------------------------------------------------------- DM Database Server 64 V8--03134284368-20250430-272000-20149 Pack1 dmdba@DAMENG:5236 SQL> @fun context dmdba@DAMENG:5236 SQL> select name,class$ from v$ifun where name like upper('%&1%'); old value 1:select name,class$ from v$ifun where name like upper('%&1%'); new value 1:select name,class$ from v$ifun where name like upper('%context%'); NAME CLASS$ ----------------- ---------------- CONTEXT_INDEX_DEF system function CONTEXTDEF context function SYS_CONTEXT context function SYS_CONTEXT context function used time: 1.860(ms). Execute id is 19911. dmdba@DAMENG:5236 SQL> dmdba@DAMENG:5236 SQL> @p COMPATIBLE_MODE dmdba@DAMENG:5236 SQL> select para_name,para_value,DEFAULT_VALUE,SESS_VALUE,FILE_VALUE,para_type,DESCRIPTION from v$dm_ini where para_name like upper('%&1%'); old value 1:select para_name,para_value,DEFAULT_VALUE,SESS_VALUE,FILE_VALUE,para_type,DESCRIPTION from v$dm_ini where para_name like upper('%&1%'); new value 1:select para_name,para_value,DEFAULT_VALUE,SESS_VALUE,FILE_VALUE,para_type,DESCRIPTION from v$dm_ini where para_name like upper('%COMPATIBLE_MODE%'); PARA_NAME PARA_VALUE DEFAULT_VALUE SESS_VALUE FILE_VALUE PARA_TYPE DESCRIPTION -------------------- ---------- ------------- ---------- ---------- --------- -------------------------------------------------------------------------------------------------------- COMPATIBLE_MODE 0 0 0 0 IN FILE Server compatible mode, 0:none, 1:SQL92, 2:Oracle, 3:MS SQL Server, 4:MySQL, 5:DM6, 6:Teradata, 7:PG CASE_COMPATIBLE_MODE 1 1 1 1 SYS Case compatible mode, 0:none, 1:Oracle(simple case), 2:Oracle(simple case new rule), 4:Oracle(bool case) XA_COMPATIBLE_MODE 0 0 0 0 SYS XA compatible mode, 0:none, 1:Oracle, 2:MySql used time: 13.766(ms). Execute id is 19912.

DM8 vs Oracle 支持差异

测试出DM8 SYS_CONTEXT namespace可以用的userenv有16项,可能还有一些自定义的没有介绍。

参数名 中文说明 DM8可用性
CURRENT_SCHEMA 当前模式名 ✅(PANDA)⭐
CURRENT_SCHEMAID 当前模式ID ✅(150995947)
CURRENT_USER 当前用户名 ✅(PANDA)⭐
CURRENT_USERID 当前用户ID ✅(50331752)
SESSION_USER 当前会话用户名 ✅(PANDA)
SESSION_USERID 当前会话用户ID ✅(50331752)⭐
DB_NAME 数据库名 ✅(DAMENG)⭐
INSTANCE_NAME 实例名 ✅(DMORCL)⭐
HOST 客户端主机名 ✅(panda101)⭐
SERVER_HOST 实例运行主机名 ✅(panda101)
IP_ADDRESS 客户端IP地址 ✅(::ffff:192.168.66.101)⭐
ISDBA 当前用户是否为DBA ✅(TRUE)
LANG 语言简写(CN/EN) ✅(EN)
LANGUAGE 语言及编码方式 ✅(ENGLISH.UTF8)
NETWORK_PROTOCOL 通信协议类型 ✅(TCP/IP)
SESSIONID / SID 当前会话标识符 ✅(195075224)
TERMINAL 当前终端或计算机名 ❌(NULL)
INSTANCE 实例号(Oracle专用)
ENTRYID 审计会话标识符
NLS_TERRITORY 当前地区设置
NLS_CURRENCY 货币符号
NLS_CALENDAR 日历类型
NLS_DATE_FORMAT 日期格式
NLS_DATE_LANGUAGE 日期语言
NLS_SORT 排序规则
PROXY_USER 代理用户
PROXY_USERID 代理用户ID
DB_DOMAIN 数据库域名
OS_USER 操作系统用户名
EXTERNAL_NAME 外部认证用户名
BG_JOB_ID 后台作业ID
FG_JOB_ID 前台作业ID
AUTHENTICATION_TYPE 用户认证方式
AUTHENTICATION_DATA 用户认证附加信息

更多 Predefined Parameters of Namespace USERENV 参照Oracle官网:https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SYS_CONTEXT.html

OB V3.2.4 SYS_CONTEXT函数:https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000948086

应用场景

常用的有CURRENT_USER、DB_NAME、INSTANCE_NAME、IP_ADDRESS、SESSIONID / SID,这些函数信息可以用来判断会话信息、区分判断生产测试环境、在SQL、存储过程、PL/SQL、Shell中判断会话信息。

使用场景1 - 区分生产与测试环境(防误操作)

比如现在一套核心的营业系统有生产和测试两套环境,如果没有进行堡垒机或者环境分离(用同一套设备就可以登陆两套环境),我们再进行一些测试变更前可以通过SYS_CONTEXT函数进行二次确认,比如测试环境数据库名字叫做bcvxxx、cs_xxx、test_xxx可以用DB_NAME、INSTANCE_NAME、IP_ADDRESS这些区分生产和测试,防止造成不可挽回的操作,尤其是删表、删库这个高危操作,一定要确认环境信息。

可以使用如下语句区分环境:

SELECT SYS_CONTEXT('USERENV','DB_NAME') AS db_name, SYS_CONTEXT('USERENV','INSTANCE_NAME') AS instance_name, SYS_CONTEXT('USERENV','IP_ADDRESS') AS ip_addr, SYS_CONTEXT('USERENV','HOST') AS client_host FROM dual; DB_NAME INSTANCE_NAME IP_ADDR CLIENT_HOST ------- ------------- ------------------- ----------- DAMENG DMORCL ::ffff:192.168.66.101 LAPTOP-xxxxxxx

使用场景2 - 结合会话视图动态过滤

用项目上常用的一个脚本举例,kill会话,通过v$sessions获取会话排除本会话:

select 'sp_close_session('|| sess_id||');--'|| USER_NAME || '@' || CLNT_HOST || ' (' || APPNAME || ');' commands_to_verify_and_run from v$sessions where &1 and sess_id != (select SYS_CONTEXT('USERENV','SESSIONID'));

在定位到行锁阻塞源的sid后可以直接生成kill脚本,并杀掉会话,执行示例:

dmdba@DAMENG:5236 SQL> @kill sess_id='195075224' COMMANDS_TO_VERIFY_AND_RUN ----------------------------------------------------- sp_close_session(195075224);--PANDA@panda101 (disql); used time: 4.766(ms). Execute id is 19914. dmdba@DAMENG:5236 SQL> sp_close_session(195075224);--PANDA@panda101 (disql); DMSQL executed successfully used time: 4.502(ms). Execute id is 19915.

会话连接超限,有部分异常用户或者用户正在执行批量DML可以根据用户名、sql_id进行匹配,批量kill,DM是单进程多线程结构不支持LOCAL=NO在操作系统层面杀,所以批量kill会话还是有必要的。

@kill <filter expression> @kill seee_id=150 @kill +seee_id|user_name|CLNT_HOST|APPNAME|sql_id @kill "event like '%lock%'"

当然这是一种思路,在编写存储过程或者脚本时没有想要的字段,结合动态视图做连接,比如写一个存储过程记录所有会话的连接信息,将登录用户、来源主机、客户端 IP,写入操作日志表通过DDL触发器记录记录执行过的sql信息,执行用户、执行时间、主机、客户端 IP、操作系统用户等

DM8 测试结果

NULL表示不支持。

panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','TERMINAL') terminal; TERMINAL -------- NULL used time: 0.253(ms). Execute id is 19822. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','LANGUAGE') language; LANGUAGE ------------ ENGLISH.UTF8 used time: 0.218(ms). Execute id is 19823. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','SESSIONID') sessionid; SESSIONID --------- 195075224 used time: 0.199(ms). Execute id is 19824. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','SID') sessionid; SESSIONID --------- 195075224 used time: 3.490(ms). Execute id is 19825. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','INSTANCE') instance; INSTANCE -------- NULL used time: 0.395(ms). Execute id is 19826. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','ENTRYID') entryid; ENTRYID ------- NULL used time: 0.282(ms). Execute id is 19827. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','ISDBA') isdba; ISDBA ----- TRUE used time: 0.262(ms). Execute id is 19828. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_TERRITORY') nls_territory; NLS_TERRITORY ------------- NULL used time: 0.338(ms). Execute id is 19829. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_CURRENCY') nls_currency; NLS_CURRENCY ------------ NULL used time: 0.290(ms). Execute id is 19830. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_CALENDAR') nls_calendar; NLS_CALENDAR ------------ NULL used time: 0.308(ms). Execute id is 19831. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') nls_date_format; NLS_DATE_FORMAT --------------- NULL used time: 0.236(ms). Execute id is 19832. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_DATE_LANGUAGE') nls_date_language; NLS_DATE_LANGUAGE ----------------- NULL used time: 0.279(ms). Execute id is 19833. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NLS_SORT') nls_sort; NLS_SORT -------- NULL used time: 0.833(ms). Execute id is 19834. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','CURRENT_USER') current_user; CURRENT_USER ------------ PANDA used time: 0.692(ms). Execute id is 19835. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','CURRENT_USERID') current_userid; CURRENT_USERID -------------- 50331752 used time: 0.608(ms). Execute id is 19836. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','SESSION_USER') session_user; SESSION_USER ------------ PANDA used time: 0.800(ms). Execute id is 19837. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','SESSION_USERID') session_userid; SESSION_USERID -------------- 50331752 used time: 1.145(ms). Execute id is 19838. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','PROXY_USER') proxy_user; PROXY_USER ---------- NULL used time: 0.765(ms). Execute id is 19839. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','PROXY_USERID') proxy_userid; PROXY_USERID ------------ NULL used time: 1.241(ms). Execute id is 19840. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','DB_DOMAIN') db_domain; DB_DOMAIN --------- NULL used time: 1.467(ms). Execute id is 19841. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','DB_NAME') db_name; DB_NAME ------- DAMENG used time: 0.854(ms). Execute id is 19842. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','HOST') host; HOST -------- panda101 used time: 0.903(ms). Execute id is 19843. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','OS_USER') os_user; OS_USER ------- NULL used time: 1.175(ms). Execute id is 19844. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','EXTERNAL_NAME') external_name; EXTERNAL_NAME ------------- NULL used time: 2.050(ms). Execute id is 19845. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','IP_ADDRESS') ip_address; IP_ADDRESS ---------- ::1 used time: 1.110(ms). Execute id is 19846. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') network_protocol; NETWORK_PROTOCOL ---------------- TCP/IP used time: 1.765(ms). Execute id is 19847. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','BG_JOB_ID') bg_job_id; BG_JOB_ID --------- NULL used time: 1.223(ms). Execute id is 19848. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','FG_JOB_ID') fg_job_id; FG_JOB_ID --------- NULL used time: 1.382(ms). Execute id is 19849. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE') authentication_type; AUTHENTICATION_TYPE ------------------- NULL used time: 18.972(ms). Execute id is 19850. panda@DAMENG:5236 SQL> select SYS_CONTEXT('USERENV','AUTHENTICATION_DATA') authentication_data; AUTHENTICATION_DATA ------------------- NULL used time: 0.609(ms). Execute id is 19851.
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服