измените псевдоним столбца и его формат отображения с помощью хранимой процедуры в Oracle PL/SQL

#oracle #plsql

Вопрос:

Это моя процедура:

 CREATE OR REPLACE PROCEDURE sp_SalHireDate_18127057
(
 salAlias VARCHAR,
 hireDateAlias VARCHAR,
 salDisplayFormat VARCHAR,
 hireDateFormat VARCHAR
)
AS
  sysRefCursor SYS_REFCURSOR;
BEGIN
  OPEN sysRefCursor FOR 
  SELECT SAL TO_CHAR(salAlias), HIREDATE TO_CHAR(hireDateAlias)
  FROM EMP_18127057;
  DBMS_SQL.RETURN_RESULT(sysRefCursor);
END;
 

Я хочу сделать следующее: при передаче псевдонима и его формата отображения(например, зарплата: от 1000 до 1000.00; дата: от дд/мм/гггг до мм/дд/гггг) процедура отобразит два столбца с псевдонимами в качестве их имен и покажет их значения в новом формате. Я все еще не разгадал код.Кто-нибудь может мне помочь, пожалуйста? Большое спасибо.

Комментарии:

1. Я не знал, что процедура может что-то вернуть. Я думаю, что ваше утверждение select должно уважать синтаксис Oracle.

2. Не делайте этого; это просто требует атак с использованием SQL-инъекций.

3. Вы можете использовать dbms_sql для возврата неявных результатов. Эта функция была добавлена в Oracle 12 для облегчения миграции с SQL Server.

4. Мой вопрос-домашнее упражнение. Пожалуйста, помогите мне решить основные проблемы.

5. Кстати, ваши варчары должны быть стандартного типа, VARCHAR2.

Ответ №1:

Вам необходимо использовать динамический SQL для включения псевдонимов в выходные данные:

 CREATE OR REPLACE PROCEDURE sp_SalHireDate_18127057
(
  salAlias         VARCHAR2,
  hireDateAlias    VARCHAR2,
  salDisplayFormat VARCHAR2,
  hireDateFormat   VARCHAR2
)
AS
  sysRefCursor SYS_REFCURSOR;
BEGIN
  OPEN sysRefCursor
  FOR 'SELECT TO_CHAR( sal, :s ) AS ' || salAlias
      || ', TO_CHAR( hiredate, :h ) AS ' || hireDateAlias
      || ' FROM EMP_18127057' USING salDisplayFormat, hireDateFormat;
  DBMS_SQL.RETURN_RESULT(sysRefCursor);
END;
/
 

Однако не делайте этого, так как вы введете атаки с использованием SQL-инъекций и сможете выполнять такие запросы, как:

 sp_SalHireDate_18127057(
  'salary',
  'hd, ( SELECT password_hash FROM secret_table WHERE username = ''ADMIN'' ) AS pwd',
  '99999999.00',
  'YYYY-MM-DD"T"HH24:MI:SS'
);
 

Который вернет дополнительный столбец и данные из таблицы, к которой вы не ожидали, что у пользователя будет доступ.


Обновить

Если вы также хотите утверждать, что псевдонимы являются простыми идентификаторами SQL, то вы можете обернуть их в вызов DBMS_ASSERT.SIMPLE_SQL_NAME :

 CREATE OR REPLACE PROCEDURE sp_SalHireDate_18127057
(
  salAlias         VARCHAR2,
  hireDateAlias    VARCHAR2,
  salDisplayFormat VARCHAR2,
  hireDateFormat   VARCHAR2
)
AS
  sysRefCursor SYS_REFCURSOR;
BEGIN
  OPEN sysRefCursor
  FOR 'SELECT TO_CHAR( sal, :s ) AS ' || DBMS_ASSERT.SIMPLE_SQL_NAME( salAlias )
      || ', TO_CHAR( hiredate, :h ) AS ' || DBMS_ASSERT.SIMPLE_SQL_NAME( hireDateAlias )
      || ' FROM EMP_18127057' USING salDisplayFormat, hireDateFormat;
  DBMS_SQL.RETURN_RESULT(sysRefCursor);
END;
/
 

Затем:

 BEGIN
  sp_SalHireDate_18127057( 'salary', 'hd, ( SELECT password_hash FROM secret_table WHERE username = ''ADMIN'' ) AS pwd', '99999999.00', 'YYYY-MM-DD"T"HH24:MI:SS' );
END;
/
 

Вывел бы:

 ORA-44003: invalid SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 215
ORA-06512: at "SCHEMA_NAME.SP_SALHIREDATE_18127057", line 11
ORA-06512: at line 2
 

бд<>скрипка <>здесь

Ответ №2:

Используйте этот выбор:

  SELECT TO_CHAR(salAlias, salDisplayFormat) SAL, TO_CHAR(hireDateAlias, hireDateFormat) HIREDATE 
 

Комментарии:

1. «процедура отобразит два столбца с псевдонимами в качестве их имен» При этом отображается псевдоним, а не значение столбца с псевдонимами.