#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. «процедура отобразит два столбца с псевдонимами в качестве их имен» При этом отображается псевдоним, а не значение столбца с псевдонимами.