尝试创建动态合并脚本并动态传递变量

Posted

技术标签:

【中文标题】尝试创建动态合并脚本并动态传递变量【英文标题】:Trying to create a dynamic merge script and passing the variables dynamically 【发布时间】:2019-11-16 09:50:33 【问题描述】:

我正在尝试创建一个动态合并脚本并动态传递变量,但该变量没有在代码中被替换。有人可以帮忙吗?

create or replace PROCEDURE MERGE_APPMODULE(institutionKey varchar2,applname varchar2,modulename varchar2,DESCRIPTION varchar2 )
as
--set serveroutput on;
--SET FEEDBACK OFF;

DATA long;
BEGIN
select

CONCAT ('declare
  institutionkey varchar2(100) := '|| '''institutionkey''' ||' ;
  actiondate DATE  := SYSDATE;
  actionuser VARCHAR2(100) := sys_context(''USERENV'', ''AUTHENTICATED_IDENTITY'');
  supportedLanguages varchar2(100) := ''en'';
BEGIN',
  '
    MERGE INTO APPMODULE TARGET 
        USING (
                SELECT  0 DISALLOW, NULL IMAGE, NULL IsMaintainence, moduleclass,1 ModuleIndex, ''modulename'' ModuleName , ApplId FROM APPLICATION WHERE  ApplName = ''applname''  and FinInstKey = ''institutionKey'')
               ) source 
        ON (
            target.ApplId=source.ApplId and target.ModuleName=source.ModuleName
            )
       WHEN NOT MATCHED THEN
          insert (createddate, creatorusr, Disallow, Image, IsDefault, IsMaintainence, moduleClass, ModuleIndex, ModuleName, updatordate, updatorusr, ApplId) 
          values (actionDate, actionUser, source.Disallow, source.Image, 1, source.IsMaintainence, source.moduleClass, source.ModuleIndex, source.ModuleName, actionDate, actionUser, source.ApplId); 

    MERGE INTO APPMODULETXT target
        USING (
                SELECT ''DESCRIPTION'' DESCRIPTION, ModuleId FROM AppModule m JOIN Application a ON m.ApplId = a.ApplId WHERE m.ModuleName = ''ACCOUNTS_SERVICES_MODULE'' AND a.ApplName = applicationName AND a.finInstKey = ''institutionKey'' 

        ) source 
        ON (
               target.ModuleId = source.ModuleId
            )
        WHEN NOT MATCHED THEN
            insert (Description, TxtLanguage, ModuleId) 
            values (source.Description, ''en'', source.ModuleId);') INTO DATA from dual;

        dbms_output.put_line(DATA);  
  END;

【问题讨论】:

我已经尝试过了,它对我有用,我想尝试一些动态的 我正在尝试的东西对我的实现很有用,所以我正在尝试这个。 如果你这么说。但是,您发布的代码绝对没有任何动态 SQL 带来的好处,同时使其更难理解且更易维护。 【参考方案1】:

你没有正确地进行串联。

可以使用|| 操作符或concat 方法连接字符串。

在您的代码中,您同时使用了两者,但发生了混乱。在这里,我尝试使用|| 运算符如下:

create or replace PROCEDURE MERGE_APPMODULE(institutionKey varchar2,applname varchar2,modulename varchar2,DESCRIPTION varchar2 )
as
--set serveroutput on;
--SET FEEDBACK OFF;

DATA VARCHAR2(32767); -- using varchar2 data type variable
BEGIN
DATA := 'declare
  institutionkey varchar2(100) := '''|| institutionkey ||''' ;
  actiondate DATE  := SYSDATE;
  actionuser VARCHAR2(100) := sys_context(''USERENV'', ''AUTHENTICATED_IDENTITY'');
  supportedLanguages varchar2(100) := ''en'';
BEGIN' || chr(10) ||
  ' MERGE INTO APPMODULE TARGET 
        USING (
                SELECT  0 DISALLOW, NULL IMAGE, NULL IsMaintainence, moduleclass,1 ModuleIndex, '''|| modulename ||''' ModuleName , ApplId FROM APPLICATION WHERE  ApplName = ''' || applname || ''' and FinInstKey = ''' || institutionKey || '''
               ) source 
        ON (
            target.ApplId=source.ApplId and target.ModuleName=source.ModuleName
            )
       WHEN NOT MATCHED THEN
          insert (createddate, creatorusr, Disallow, Image, IsDefault, IsMaintainence, moduleClass, ModuleIndex, ModuleName, updatordate, updatorusr, ApplId) 
          values (actionDate, actionUser, source.Disallow, source.Image, 1, source.IsMaintainence, source.moduleClass, source.ModuleIndex, source.ModuleName, actionDate, actionUser, source.ApplId); 

    MERGE INTO APPMODULETXT target
        USING (
                SELECT ''' || DESCRIPTION || ''' DESCRIPTION, ModuleId FROM AppModule m JOIN Application a ON m.ApplId = a.ApplId WHERE m.ModuleName = ''ACCOUNTS_SERVICES_MODULE'' AND a.ApplName = applicationName AND a.finInstKey = ''' || institutionKey || '''  
               ) source 
        ON (
               target.ModuleId = source.ModuleId
            )
        WHEN NOT MATCHED THEN
            insert (Description, TxtLanguage, ModuleId) 
            values (source.Description, ''en'', source.ModuleId);';

        dbms_output.put_line(DATA);  
  END;

检查它是否适合你。

干杯!!

【讨论】:

感谢 Tejash!,您的代码正在运行,我的代码也已修复 :)【参考方案2】:

为什么在本世纪使用 LONG 类型? 自从 1997 年 Oracle 8.0 发布以来,它已经有点被弃用了。

使用 CLOB 通常会使您的生活变得更轻松,但在这种情况下,即使是 VARCHAR2 也可能足够大以适合您的查询。

【讨论】:

以上是关于尝试创建动态合并脚本并动态传递变量的主要内容,如果未能解决你的问题,请参考以下文章

动态更改PHP变量(在执行时)

动态命名apple脚本变量

LR静态存储/动态存储/指针变量脚本说明

如何将动态创建的.xml文件与主AndroidManifest.xml合并

如何在 shell 脚本中动态生成新的变量名?

如何使用Scriptable Objects创建动态变量系统