林笙不苼 2024-10-05 19:35 采纳率: 0%
浏览 4

python实现SQL语句转换

为什么输出结果老是带@,而且WHILE不在BEGIN-END循环体中,导致输出结果无法在Pg中运行


```python
import re
import os

def convert_sql_server_to_postgresql(sql):
    # 替换 SQL Server 的自增语法
    sql = re.sub(r'IDENTITY\(\d+,\s*\d+\)', 'SERIAL', sql)

    # 替换 PRINT 为 RAISE NOTICE
    sql = re.sub(r'PRINT\s+', 'RAISE NOTICE ', sql)

    # 替换变量声明
    sql = re.sub(r'DECLARE\s+@(\w+)\s+([A-Z]+)', r'DECLARE \1 \2', sql)

    # 替换 SET 语句
    sql = re.sub(r'SET\s+@(\w+)\s*=\s*(.+);', r'\1 := \2;', sql)

    # 替换 WHILE 循环结构
    sql = re.sub(r'WHILE\s+(.+?)\s+BEGIN', r'WHILE \1 LOOP', sql)
    sql = re.sub(r'END', 'END LOOP;', sql)

    # 处理 SELECT TOP N(这里需要更复杂的处理)
    sql = re.sub(r'SELECT TOP (\d+)', r'SELECT', sql)
    # 先不直接替换 LIMIT,因为需要处理具体的 SELECT 语句内容

    # 其他转换可以继续添加...

    # 修改 DECLARE 和其他语法
    postgresql_code = sql.replace(';', '')

    # 添加 DO 块和结束语句
    if "BEGIN" in postgresql_code:
        postgresql_code = "DO $$\nDECLARE\n" + postgresql_code.split("BEGIN")[0].strip() + ";\nBEGIN\n" + postgresql_code.split("BEGIN")[1] + "\nEND $$;"
    else:
        postgresql_code = "DO $$\nBEGIN\n" + postgresql_code + "\nEND $$;"

    return postgresql_code

def main():
    print("请输入 SQL Server 的 WHILE 循环 SQL 语句(以 `QUIT` 结束):")

    sql_server_code = ""
    while True:
        line = input()
        if line.strip().upper() == "QUIT":
            break
        sql_server_code += line + "\n"

    # 转换 SQL 语句
    converted_code = convert_sql_server_to_postgresql(sql_server_code)

    # 保存转换后的 SQL 语句到输出文件
    output_file_path = os.path.join(os.path.expanduser('~'), 'while_loop.sql')
    try:
        with open(output_file_path, 'w') as file:
            file.write(converted_code)
        print("转换完成,结果已保存至:", output_file_path)
    except Exception as e:
        print("保存文件时出错:", e)

if __name__ == "__main__":
    main()

输入:

DECLARE @counter INT
SET @counter = 0
WHILE @counter < 10
BEGIN
    PRINT @counter
    SET @counter = @counter + 1
END

预期输出(pgSQL语句):



DO $$
DECLARE
counter INT;
BEGIN
    counter := 0;
    WHILE counter < 10 LOOP
        RAISE NOTICE 'Counter: %', counter;
        counter := counter + 1;
    END LOOP;
END $$;

实际输出(pgSQL语句)

DO $$
DECLARE
DECLARE counter INT = 0

WHILE @counter < 5;
BEGIN

    RAISE NOTICE @counter
    := @counter = @counter + 1
END

END $$;

img

  • 写回答

3条回答 默认 最新

  • 一轮明月照丘壑 2024-10-05 19:36
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从您的描述和提供的代码来看,有几个问题需要解决。让我们逐一解决这些问题。

    问题一:输出中的 @ 符号问题。在 SQL Server 中使用 @ 来声明变量,但在 PostgreSQL 中不需要这个符号。在转换过程中,需要将其移除。但在您的代码中,似乎没有正确处理这种情况。特别是在 SET @counter = @counter + 1 的转换中,@counter 符号没有被正确处理。因此,我们需要对这部分进行修正。此外,PostgreSQL 中不需要 DECLARE counter INT = 0 这样的语法来初始化变量,我们可以直接使用 counter := 0 进行赋值。下面是修正后的代码片段:

    # ...其他代码不变...
    
    # 替换 SET 语句,正确处理变量赋值和声明
    sql = re.sub(r'SET\s+(\w+)\s*=\s*(.+);', r'\1 := \2', sql)  # 修改这里,移除分号并正确处理变量赋值
    
    # ...其他代码不变...
    

    在修正后的代码中,我们将 SET @counter = @counter + 1 转换为 counter := counter + 1,移除了 @ 符号并保留了正确的赋值语法。同时,由于 PostgreSQL 中变量的声明和赋值可以在同一行完成,因此我们不需要单独声明变量后再进行赋值。

    问题二:WHILE 循环的转换问题。您的代码已经包含了 WHILE 循环的转换逻辑,看起来是正确的。但是需要注意确保 BEGIN 和 END 块中的语句正确缩进,以便在 PostgreSQL 中能够正确运行。您提供的输出中似乎缺少了必要的缩进,这是导致无法在 PostgreSQL 中运行的原因之一。在转换后的代码中确保语句的缩进是正确的。

    问题三:关于 DO 块和 END 语句的添加问题。您的代码已经包含了添加 DO 块和 END 语句的逻辑,这部分看起来是正确的。只要确保输入 SQL 的格式正确,这部分逻辑应该能够正常工作。不过需要注意的是,如果您的输入 SQL 已经包含了 BEGIN 和 END 块,那么添加 DO 块和 END 语句的逻辑可能会导致重复或冲突。您的代码似乎没有处理这种情况,可能需要添加额外的逻辑来处理这种情况。例如检查是否已经存在 BEGIN 和 END 块来决定是否添加 DO 块和 END 语句。

    综上所述,您需要修正变量赋值的处理逻辑并确保正确的缩进和格式。同时考虑是否需要添加额外的逻辑来处理已经存在 BEGIN 和 END 块的情况。这样应该能够解决您的问题并生成正确的 PostgreSQL 代码。

    评论

报告相同问题?

问题事件

  • 创建了问题 10月5日

悬赏问题

  • ¥15 Apache显示系统错误3该如何解决?
  • ¥30 uniapp小程序苹果手机加载gif图片不显示动效?
  • ¥20 js怎么实现跨域问题
  • ¥15 C++dll二次开发,C#调用
  • ¥15 请教,如何使用C#加载本地摄像头进行逐帧推流
  • ¥15 Python easyocr无法顺利执行,如何解决?
  • ¥15 为什么会突然npm err!啊
  • ¥15 java服务连接es读取列表数据,服务连接本地es获取数据时的速度很快,但是换成远端的es就会非常慢,这是为什么呢
  • ¥15 vxworks交叉编译gcc报错error: missing binary operator before token "("
  • ¥15 JSzip压缩文件时如何设置解压缩密码