You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL Server存储过程与UDF迁移转换至PostgreSQL?

问题

现有包含表、视图、函数及存储过程的SQL Server数据库,已成功将表导出迁移至PostgreSQL,但无法将用户定义函数(UDF)和存储过程转换为PostgreSQL兼容版本。

已尝试的方案
  • 多个开源转换工具:包括sqlserver2pgsql、CodeProject上的SQL Server转PostgreSQL方案
  • 自行编写C#转换方法:
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public static void ConvertMSSQLToPostgreSQL(string input, string outputFilePath)
{
    // 定义SQL Server到PostgreSQL的数据类型映射
    var dataTypeMappings = new Dictionary<string, string>()
    {
        { "INT", "INTEGER" },
        { "BIGINT", "BIGINT" },
        { "SMALLINT", "SMALLINT" },
        { "FLOAT", "FLOAT" },
        { "REAL", "REAL" },
        { "NUMERIC", "NUMERIC" },
        { "MONEY", "MONEY" },
        { "BIT", "BOOLEAN" },
        { "CHAR", "CHAR" },
        { "VARCHAR", "VARCHAR" },
        { "TEXT", "TEXT" },
        { "DATE", "DATE" },
        { "TIME", "TIME" },
        { "DATETIME", "TIMESTAMP" }
    };

    // 定义SQL Server到PostgreSQL的运算符映射
    var operatorMappings = new Dictionary<string, string>()
    {
        { "=", "=" },
        { "<>", "<>" },
        { "!=", "<>" },
        { "<", "<" },
        { "<=", "<=" },
        { ">", ">" },
        { ">=", ">=" },
        { "+", "+" },
        { "-", "-" },
        { "*", "*" },
        { "/", "/" },
        { "%", "%" },
        { "AND", "AND" },
        { "OR", "OR" },
        { "NOT", "NOT" }
    };

    // 生成匹配数据类型的正则模式
    var dataTypePattern = string.Join("|", dataTypeMappings.Keys);

    // 生成匹配运算符的正则模式
    var operatorPattern = string.Join("|", operatorMappings.Keys);

    // 匹配存储过程参数的正则模式
    var parameterPattern = @"(@\w+)\s+(?:" + dataTypePattern + @")(\([^)]+\))?";

    // 匹配运算符的替换正则模式
    var operatorReplacePattern = @"(?<![\w\d])(" + operatorPattern + @")(?![\w\d])";

    // 匹配数据类型的替换正则模式
    var dataTypeReplacePattern = @"(?<![\w\d])(" + dataTypePattern + @")(?![\w\d])";

    // 替换数据类型和运算符为PostgreSQL等价形式
    var output = Regex.Replace(input, dataTypeReplacePattern, match => dataTypeMappings[match.Value]);
    output = Regex.Replace(output, operatorReplacePattern, match => operatorMappings[match.Value]);

    // 替换存储过程参数为PostgreSQL等价形式
    output = Regex.Replace(output, parameterPattern, match =>
    {
        var parameterName = match.Groups[1].Value;
        var dataType = match.Groups[2].Success ? match.Groups[2].Value.TrimStart('(').TrimEnd(')') : "VARCHAR";
        return parameterName + " " + dataTypeMappings[dataType];
    });

    // 将转换后的PostgreSQL存储过程写入文本文件
    File.WriteAllText(outputFilePath, output);
}
  • 在SQL Server中创建UDF生成PostgreSQL兼容语句:
CREATE FUNCTION [dbo].[udf_sp_to_postgres](@sp_name sysname) RETURNS nvarchar(max)
AS
BEGIN
  DECLARE @schema_name sysname = OBJECT_SCHEMA_NAME(OBJECT_ID(@sp_name));
  DECLARE @sp_base_name sysname = OBJECT_NAME(OBJECT_ID(@sp_name));
  DECLARE @arg_types nvarchar(max) = '';
  DECLARE @arg_names nvarchar(max) = '';
  DECLARE @arg_modes nvarchar(max) = '';
  DECLARE @sp_def nvarchar(max) = '';

  SELECT @sp_def = definition
  FROM sys.sql_modules
  WHERE object_id = OBJECT_ID(@sp_name);

  -- 检查存储过程是否有参数
  IF (EXISTS(SELECT * FROM sys.parameters WHERE object_id = OBJECT_ID(@sp_name))) BEGIN
    SELECT @arg_types = STRING_AGG(QUOTENAME(t.name), ',')
    FROM sys.parameters p
    JOIN sys.types t ON p.system_type_id = t.system_type_id AND t.user_type_id = p.user_type_id
    WHERE p.object_id = OBJECT_ID(@sp_name)
   -- ORDER BY p.parameter_id;

    SELECT @arg_names = STRING_AGG(QUOTENAME(p.name), ',')
    FROM sys.parameters p
    WHERE p.object_id = OBJECT_ID(@sp_name)
  --  ORDER BY p.parameter_id;

    SELECT @arg_modes = STRING_AGG(CASE p.is_output
                                    WHEN 1 THEN 'OUT'
                                    ELSE 'IN'
                                  END + ' ' + QUOTENAME(p.name) + ' ' + QUOTENAME(t.name), ',')
    FROM sys.parameters p
    JOIN sys.types t ON p.system_type_id = t.system_type_id AND t.user_type_id = p.user_type_id
    WHERE p.object_id = OBJECT_ID(@sp_name)
   -- ORDER BY p.parameter_id;

    SET @arg_types = RIGHT(@arg_types, LEN(@arg_types) - 1);
    SET @arg_names = RIGHT(@arg_names, LEN(@arg_names) - 1);
    SET @arg_modes = RIGHT(@arg_modes, LEN(@arg_modes) - 1);
  END;

  RETURN 'CREATE OR REPLACE FUNCTION ' + QUOTENAME(@schema_name) + '.' + QUOTENAME(@sp_base_name) +
         '(' + @arg_modes + ') RETURNS void AS $$' + REPLACE(@sp_def, '$', '$$') +
         '$$ LANGUAGE plpgsql;';
END;
  • 视频教程中的SQL Server脚本生成方法
需求

希望通过存储过程或C#库完成SQL Server UDF和存储过程到PostgreSQL的转换工作。


内容的提问来源于stack exchange,提问作者Asjal Rana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 00:15:23