Trivadis / plsql-cop-cli

db* CODECOP Command Line

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Substitution variables

NikLoginov opened this issue · comments

How can i check files with substitution variables in my scripts?
For example:

CREATE TABLE &&emp..locations (
   location_id   NUMBER(10)        NOT NULL,
   location_name VARCHAR2(60 CHAR) NOT NULL,
   city          VARCHAR2(30 CHAR) NOT NULL,
   CONSTRAINT locations_pk PRIMARY KEY (location_id)
);

CREATE SEQUENCE &&emp..location_seq START WITH 1 CACHE 20;

CREATE OR REPLACE TRIGGER &&emp..location_br_i
   BEFORE INSERT ON &&emp..locations
   FOR EACH ROW
BEGIN
   :new.location_id := location_seq.nextval;
END;
/

CREATE TABLE &&emp..locations (
   location_id   NUMBER(10) GENERATED ALWAYS AS IDENTITY,
   location_name VARCHAR2(60 CHAR) NOT NULL,
   city          VARCHAR2(30 CHAR) NOT NULL,
   CONSTRAINT locations_pk PRIMARY KEY (location_id)
);

tvdcc.cmd path="sample\sample"

Result:

E-0002: Syntax error. Please contact the author if the code compiles successfully in your environment.

Substitution variable can contain code snippets. They need to be processed before the code analysis. PL/SQL Cop cannot process substitution variables and it's not planned to implement that.

However, the shallow parser for SQL*Plus can deal with all objects that are not considered for code analysis. See PL/SQL Parser for a complete list of objects that are considered for code analysis.

In this case the create trigger statement contains substitution variables. And therefore you get the E-0002 error.

We suggest to keep the PL/SQL code in dedicated files and avoid substitution variables in these objects.

In your case the substitution variable contains the schema name. So, I guess the code can be deployed in several schemas. therefore I suggest to use ALTER SESSION SET CURRENT_SCHEMA = &&emp; instead.

The following adapted code can be processed:

CREATE TABLE &&emp..locations (
   location_id   NUMBER(10)        NOT NULL,
   location_name VARCHAR2(60 CHAR) NOT NULL,
   city          VARCHAR2(30 CHAR) NOT NULL,
   CONSTRAINT locations_pk PRIMARY KEY (location_id)
);

CREATE SEQUENCE &&emp..location_seq START WITH 1 CACHE 20;

ALTER SESSION SET CURRENT_SCHEMA = &&emp;

CREATE OR REPLACE TRIGGER location_br_i
   BEFORE INSERT ON locations
   FOR EACH ROW
BEGIN
   :new.location_id := location_seq.nextval;
END;
/

CREATE TABLE &&emp..locations (
   location_id   NUMBER(10) GENERATED ALWAYS AS IDENTITY,
   location_name VARCHAR2(60 CHAR) NOT NULL,
   city          VARCHAR2(30 CHAR) NOT NULL,
   CONSTRAINT locations_pk PRIMARY KEY (location_id)
);

I hope this helps.