注册
SQLSERVER/KINGBASE转达梦数据库遇到的问题
专栏/培训园地/ 文章详情 /

SQLSERVER/KINGBASE转达梦数据库遇到的问题

DM_195387 2024/06/06 896 2 0
摘要
  1. 大小写
    达梦的大小写也不是绝对意义上的大小写,同时和金仓的大小写也不太一样,
    金仓: "name", "NAME",name, NAME,Name 是相同的标识符
    达梦:"NAME",name, NAME,Name 是相同的,不同于 "name"
    开发过程中应该注意兼容,
    建议做法就是不管带不带双引号,使用绝对意义上的大小写,例如数据库定义的是name,真实的写法是NAME,那么建议在任何场景都直接只用真实写法NAME,避免一切与真实写法意义相同但是写法不同的情况。
    金仓数据库:
SELECT TOP 10 * FROM SPD_DYBK
SELECT TOP 10 * FROM spd_dybk
SELECT TOP 10 * FROM SPD_dybk
SELECT TOP 10 * FROM "spd_dybk"
-- 以上都是正确的
 
SELECT TOP 10 * FROM "SPD_dybk"
-- 这条是错误的

达梦数据库

SELECT TOP 10 * FROM "dbo".SPD_DYBK
SELECT TOP 10 * FROM "dbo".spd_dybk
SELECT TOP 10 * FROM "dbo".SPD_dybk
-- 以上都是正确的
 
SELECT TOP 10 * FROM "dbo"."SPD_dybk"
SELECT TOP 10 * FROM "dbo"."spd_dybk"   ----------这种写法的和金仓不一样
-- 这两条是错误的

  1. 临时表
    达梦数据库在存储过程中是不能直接执行DDL语句的,如果有必要,需要通过EXECUTE IMMEDIATE执行动态语句操作。
    一般建议在外部创建全局临时表或物理表,在存储中执行对该表的插入删除等操作。
    临时表示例
    EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE IF NOT EXISTS "dbo".SPD_USP_SYS_CZPZ_TMP (MC VARCHAR(36), PX INT, VAL VARCHAR(8188)) ON COMMIT DELETE ROWS';
END;
 
CREATE OR REPLACE   PROCEDURE "dbo"."SPD_USP_SYS_CZPZ" ( DM_id   NVARCHAR(36) , DM_yydm   VARCHAR(36) , DM_awdv   BIT = 0)
AS 
    DM_columns  NVARCHAR(8188);
    DM_sql  NVARCHAR(8188);
BEGIN     
    SELECT  ID INTO   DM_id  FROM    "dbo".SPD_CSPZ  WHERE   ID = DM_id OR DM = DM_id;      
       
    SELECT  STUFF(( SELECT cast(xmlagg(''||   ',''' ||  MC || '_' || CONVERT( VARCHAR(2),PX)||'''' ) as varchar2) as xml_content
                           FROM     "dbo".SPD_CSPZY  WHERE    PZID = DM_id ORDER BY PX ), 1, 1, '') INTO   DM_columns ;
    IF NOT EXISTS ( SELECT  PX FROM "dbo".SPD_CSPZZ WHERE YYDM = DM_yydm AND PZID = DM_id ) THEN
        SET DM_yydm = '';           
    END IF;
       
    INSERT  INTO "dbo".SPD_USP_SYS_CZPZ_TMP (MC , PX , VAL )
        SELECT  m.MC || '_'||CONVERT( VARCHAR(2),m.PX)  AS MC , p.PX , ISNULL(v.PZZ, m.MRZ) AS PZZ
        FROM    "dbo".SPD_CSPZY m
        INNER JOIN ( SELECT DISTINCT PZID , PX FROM   "dbo".SPD_CSPZZ  WHERE  YYDM =  DM_yydm AND PZID = DM_id ) p ON p.PZID = m.PZID
        LEFT JOIN "dbo".SPD_CSPZZ v  ON m.PX = v.PZYPX AND p.PX = v.PX AND v.YYDM = DM_yydm AND v.PZID = DM_id;
     
    IF SQL%ROWCOUNT  = 0 AND DM_awdv = 1 THEN
        INSERT  INTO "dbo".SPD_USP_SYS_CZPZ_TMP (MC , PX , VAL )
        SELECT  m.MC || '_'||CONVERT( VARCHAR(2),m.PX)  , 0 AS PX , m.MRZ AS PZZ FROM    "dbo".SPD_CSPZY m  WHERE   PZID = DM_id;
    END IF;         
     
    SET DM_sql = 'SELECT * FROM "dbo".SPD_USP_SYS_CZPZ_TMP AS t1 PIVOT (MIN(VAL) FOR MC IN(' ||  DM_columns ||  ')) AS t2 ORDER BY PX';
    EXECUTE IMMEDIATE  DM_sql;
END;

  1. 大文本
    在SqlServer数据库中的text类型,迁移到达梦数据库默认类型是:Clob 长文本类型
    在jdbc查询后,在数据集中的类型是DmdbNClob,需要转换成文本。
    可使用统一转换方法:
if (obj.getClass() == dm.jdbc.driver.DmdbNClob.class) { dm.jdbc.driver.DmdbNClob nClob = (dm.jdbc.driver.DmdbNClob) obj; Reader reader = nClob.getCharacterStream(); // 或者使用 getAsciiStream() BufferedReader bufferedReader = new BufferedReader(reader); StringBuilder stringBuilder = new StringBuilder(); char[] charBuffer = new char[8192]; int bytesRead; while ((bytesRead = bufferedReader.read(charBuffer)) != -1) { stringBuilder.append(charBuffer, 0, bytesRead); } String nClobString = stringBuilder.toString(); return nClobString; }
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服