跳至主要內容

KlustronDB大约 5 分钟

以下是SQL Server 专属函数-替代方案对照表,按功能分类整理,包含用途说明、SQL Server 示例及 PostgreSQL/MySQL 的替代写法,迁移时可直接参考:

函数分类SQL Server 函数用途说明SQL Server 示例PostgreSQL 替代方案MySQL 替代方案
XML 处理nodes()将 XML 节点拆解为关系型行集(行转列核心函数)SELECT T.c.query('.') FROM tab CROSS APPLY xml_col.nodes('/root/node') T(c)SELECT x.* FROM tab, xmltable('/root/node' passing xml_col columns val xml path '.') x(需 PostgreSQL 9.3+)无直接函数,需用 ExtractValue(xml_col, '/root/node[$i]/text()') 结合循环(需手动控制索引 $i
query()执行 XQuery 表达式查询 XML 片段SELECT xml_col.query('/root/node[@id=1]') FROM tabSELECT (xpath('/root/node[@id=1]', xml_col))[1]::xmlxpath 函数返回数组,取第一个元素)SELECT ExtractValue(xml_col, '/root/node[@id=1]')(仅支持简单路径,不支持复杂XQuery)
value()从 XML 节点提取指定类型的值SELECT xml_col.value('(/root/node/text())[1]', 'int') FROM tabSELECT (xpath('/root/node/text()', xml_col))[1]::int(数组转指定类型)SELECT ExtractValue(xml_col, '/root/node[1]/text()') + 0(通过运算强制类型转换)
modify()直接修改 XML 节点(插入/更新/删除)UPDATE tab SET xml_col.modify('replace value of (/root/node/text())[1] with "new"')无直接函数,需用字符串函数拼接新XML:UPDATE tab SET xml_col = regexp_replace(xml_col::text, '<node>.*?</node>', '<node>new</node>')::xml无直接函数,用 REPLACE(xml_col, '旧值', '新值') 字符串替换(仅限简单场景)
exist()判断 XML 中是否存在符合条件的节点(返回 1/0)SELECT CASE WHEN xml_col.exist('/root/node') = 1 THEN '存在' ELSE '不存在' ENDSELECT CASE WHEN xpath_exists('/root/node', xml_col) THEN '存在' ELSE '不存在' END(PostgreSQL 10+)SELECT CASE WHEN ExtractValue(xml_col, 'count(/root/node)') > 0 THEN '存在' ELSE '不存在' END
聚合/窗口函数STRING_AGG(expr, sep)按分组聚合字符串(参数:表达式+分隔符)SELECT dept, STRING_AGG(emp_name, ',') FROM emp GROUP BY deptSELECT dept, string_agg(emp_name, ',') FROM emp GROUP BY dept(函数名小写,参数顺序相同)SELECT dept, GROUP_CONCAT(emp_name SEPARATOR ',') FROM emp GROUP BY dept(默认分隔符为逗号,需指定SEPARATOR)
FIRST_VALUE(expr) OVER(ORDER BY col ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW IGNORE NULLS)取窗口内首个非空值(带 IGNORE NULLSSELECT FIRST_VALUE(score IGNORE NULLS) OVER(ORDER BY id) FROM stuSELECT FIRST_VALUE(score) OVER(ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM stu(PostgreSQL 13+ 支持 IGNORE NULLS,低版本需用 CASE 过滤)SELECT FIRST_VALUE(score) OVER(ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM stu(MySQL 8.0+ 支持,但不直接支持 IGNORE NULLS,需用 CASE WHEN score IS NOT NULL THEN score END 预处理)
安全/权限SUSER_SNAME(login_id)通过登录ID获取登录名(服务器级用户)SELECT SUSER_SNAME(101) AS login_nameSELECT rolname FROM pg_authid WHERE oid = 101pg_authid 存储登录角色信息)SELECT user FROM mysql.user WHERE Host = 'localhost' AND user_id = 101(需结合主机名过滤)
OBJECTPROPERTY(obj_id, 'IsView')判断对象是否为视图(返回 1/0)SELECT OBJECTPROPERTY(OBJECT_ID('dbo.v1'), 'IsView')SELECT CASE WHEN relkind = 'v' THEN 1 ELSE 0 END FROM pg_class WHERE relname = 'v1' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dbo')relkind='v' 表示视图)SELECT CASE WHEN table_type = 'VIEW' THEN 1 ELSE 0 END FROM information_schema.tables WHERE table_name = 'v1' AND table_schema = 'dbo'
元数据查询COL_LENGTH('table', 'col')获取列的长度(如 varchar(50) 返回 50)SELECT COL_LENGTH('emp', 'name')SELECT character_maximum_length FROM information_schema.columns WHERE table_name = 'emp' AND column_name = 'name' AND table_schema = 'dbo'SELECT character_maximum_length FROM information_schema.columns WHERE table_name = 'emp' AND column_name = 'name' AND table_schema = 'dbo'
OBJECT_ID('schema.obj')获取对象的唯一ID(如表、视图)SELECT OBJECT_ID('dbo.emp') AS obj_idSELECT oid FROM pg_class WHERE relname = 'emp' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'dbo')oid 为PostgreSQL对象唯一ID)SELECT table_id FROM information_schema.tables WHERE table_name = 'emp' AND table_schema = 'dbo'(MySQL 8.0+ 支持 table_id
日期时间DATEADD(interval, num, date)日期加减(支持 year/month/day/hour 等单位)SELECT DATEADD(day, 3, '2023-01-01')(加3天)SELECT '2023-01-01'::date + interval '3 days'(用 interval 关键字,单位为复数)SELECT DATE_ADD('2023-01-01', INTERVAL 3 DAY)(单位为单数,参数顺序:日期+间隔)
DATEDIFF(interval, start, end)计算两个日期的差值(返回整数)SELECT DATEDIFF(month, '2023-01-01', '2023-03-01')(返回2)SELECT EXTRACT(year FROM age('2023-03-01'::date, '2023-01-01'::date)) * 12 + EXTRACT(month FROM age('2023-03-01'::date, '2023-01-01'::date))(通过 age 函数拆解年月)SELECT TIMESTAMPDIFF(MONTH, '2023-01-01', '2023-03-01')(参数顺序:单位+开始+结束)
其他工具函数PARSENAME('obj', level)按点拆分对象名(如 'a.b.c.d' 拆分为4部分,level=1取最后一部分)SELECT PARSENAME('dbo.emp.name', 2)(返回 'emp')SELECT split_part('dbo.emp.name', '.', 2)split_part 按分隔符拆分,索引从1开始)SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('dbo.emp.name', '.', 2), '.', -1)(先取前2部分,再取最后1部分)
FORMATMESSAGE('模板 %d %s', 1, 'a')格式化字符串(类似 sprintf)SELECT FORMATMESSAGE('ID: %d, Name: %s', 10, 'Tom')(返回 'ID: 10, Name: Tom')SELECT format('ID: %s, Name: %s', 10, 'Tom')format 函数,占位符统一为 %s,自动转换类型)SELECT CONCAT('ID: ', 10, ', Name: ', 'Tom')(用 CONCAT 拼接,或 FORMAT(10, 'ID: %d, Name: Tom') 有限支持)
NULLIFZERO(num)若数值为0则返回NULL,否则返回原数值SELECT NULLIFZERO(0) (返回NULL)、SELECT NULLIFZERO(5)(返回5)SELECT CASE WHEN 0 = 0 THEN NULL ELSE 0 ENDSELECT CASE WHEN 5 = 0 THEN NULL ELSE 5 ENDSELECT CASE WHEN 0 = 0 THEN NULL ELSE 0 ENDSELECT CASE WHEN 5 = 0 THEN NULL ELSE 5 END

关键说明:

  1. 版本差异:部分替代函数依赖数据库版本(如 PostgreSQL 的 xpath_exists 需 10+,MySQL 的窗口函数需 8.0+),迁移前需确认目标库版本。
  2. XML 功能限制:PostgreSQL 的 XML 处理依赖 xpath 系列函数,功能弱于 SQL Server;MySQL 的 XML 支持更基础,复杂场景建议先将 XML 解析为关系表。
  3. 元数据查询:PostgreSQL 依赖 pg_* 系统表(如 pg_classpg_namespace),MySQL 依赖 INFORMATION_SCHEMA,需注意架构(schema)的映射关系(SQL Server 的 dbo 通常对应 PostgreSQL/MySQL 的 public 或自定义 schema)。

如果需要某类函数的更复杂场景示例,可以进一步补充说明!