我需要撰寫一個程式,其中將有表名作為輸入引數(一次應該只有一個表)和列名(應該有多個列名逗號分隔)和列值(應該有多個列名逗號分隔)。
我的嘗試:
CREATE OR REPLACE PROCEDURE sp_test_insert(
p_table_name IN VARCHAR2,
p_column_name IN VARCHAR2,-- It can have multiple column names separated by comma
p_column_value IN VARCHAR2-- It can have multiple column names separated by
)
AS
lv_str VARCHAR2(4000);
BEGIN
lv_str := 'INSERT INTO '||p_table_name||'should have multiple column names' ||
'VALUES('||'should have multiple column names' ||')';
EXECUTE IMMEDIATE lv_str;
END;
Tool used: SQL Developer(18c)
我被困在如何處理程序主體內的多個列名和列值上。我將如何定義一個陣列并相應地進行?
uj5u.com熱心網友回復:
不。您正在為自己設定一個容易受到 SQL 注入攻擊的程序。
如果你真的想(請不要):
CREATE OR REPLACE PROCEDURE sp_test_insert(
p_table_name IN VARCHAR2,
p_column_name IN VARCHAR2,
p_column_value IN VARCHAR2
)
AS
lv_str VARCHAR2(4000);
BEGIN
lv_str := 'INSERT INTO '||p_table_name||' (' || p_column_name || ') VALUES(' || p_column_value ||')';
EXECUTE IMMEDIATE lv_str;
END;
/
然后你可以這樣做:
BEGIN
sp_test_insert(
'my_table',
'col1, col2, col3',
q'['a', DATE '2022-05-31', 42]'
);
END;
/
但你也可以這樣做:
BEGIN
sp_test_insert(
'my_table',
'col1, col2, col3',
q'['a', (SELECT DATE '1970-01-01' FROM secret_table WHERE username = 'Admin' AND password_hash = 'abcgefg1234'), 42]'
);
END;
/
不要讓您的應用程式容易受到 SQL 注入攻擊;如果您能提供幫助,請避免使用動態 SQL!
如果你想讓它更能抵抗 SQL 注入攻擊,那么你可以使用這個DBMS_ASSERT包:
CREATE OR REPLACE PROCEDURE sp_test_insert(
p_table_name IN VARCHAR2,
p_column_name IN SYS.ODCIVARCHAR2LIST,
p_column_value IN SYS.ODCIVARCHAR2LIST
)
AS
lv_str VARCHAR2(4000);
BEGIN
lv_str := 'INSERT INTO '
|| DBMS_ASSERT.SQL_OBJECT_NAME(
DBMS_ASSERT.ENQUOTE_NAME(p_table_name, FALSE)
)
||' ('
|| DBMS_ASSERT.ENQUOTE_NAME(p_column_name(1), FALSE);
FOR i IN 2 .. p_column_name.COUNT LOOP
lv_str := lv_str || ', '
|| DBMS_ASSERT.ENQUOTE_NAME(p_column_name(i), FALSE);
END LOOP;
lv_str := lv_str || ') VALUES('
|| DBMS_ASSERT.ENQUOTE_LITERAL(p_column_value(1));
FOR i IN 2 .. p_column_name.COUNT LOOP
lv_str := lv_str || ', '
|| DBMS_ASSERT.ENQUOTE_LITERAL(p_column_value(i));
END LOOP;
lv_str := lv_str || ')';
EXECUTE IMMEDIATE lv_str;
END;
/
然后:
BEGIN
sp_test_insert(
'MY_TABLE',
SYS.ODCIVARCHAR2LIST( 'COL1', 'COL2', 'COL3'),
SYS.ODCIVARCHAR2LIST( 'a', '31-MAY-2022', '42')
);
END;
/
但是,這些值現在都作為字串傳遞到動態 SQL 陳述句中,這使得將資料傳遞到或(等)列變得更加困難DATE,因為它依賴于隱式資料型別轉換。TIMESTAMPINTERVAL
如果可能,您仍應避免使用動態 SQL。
db<>在這里擺弄
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/484736.html
