I have done right click on the SP and the right side has an embedded table that has the params but I can't seem to enter the params there. I was able to do what I needed in PL SQL but how do I run SP's now?
you can run via block of plsql code.
if you want to run only you can use following types of block--
declare
/*
parameter declaration .. just like your parameter types in SP.
like ..
*/
l_p_input_1 varchar2(980):= '<value you want to give>';
l_p_input_2 number := 33;
l_p_output_1 varchar2(889);
begin
sp_your_sP_name(l_p_input_1,
l_p_input_2,
l_p_output_1);
dbms_output.put_line('l_p_output_1 : '||l_p_output_1);
end;
Related
We have some few packages where we need to resolve some SQL Injection issues. I need some help to rewrite sql statement or sanitize the inputs. Below is the line number where veracode throw the error.
open c_ccl (p_part_nr,p_ctry_cd);
// Source code
CREATE OR REPLACE EDITIONABLE PACKAGE BODY "schema"."Test_PKG" AS
v_data t_cla_class_data;
FUNCTION nat_eccn_cd( p_part_nr IN t_part_nr, p_ctry_cd IN t_ctry_cd )
RETURN t_us_eccn_cd IS
CURSOR c_ccl(p_part_nr CHAR, p_ctry_cd CHAR) IS
SELECT NAT_CCL_CD FROM CLSDBA.CLA_EXP_PART_CTRY e
WHERE e.PART_NR = p_part_nr AND e.CTRY_CD = p_ctry_cd
ORDER BY e.VAL_FROM_DT DESC;
v_ctry_cd char(4) := p_ctry_cd;
v_trf_cd char(4);
BEGIN
v_data.nat_eccn_cd := NULL;
open c_ccl (p_part_nr,p_ctry_cd);
fetch c_ccl INTO v_data.nat_eccn_cd;
close c_ccl;
return (trim(v_data.nat_eccn_cd));
exception when others then return NULL;
end;
I don't see any SQL injection issues with your code - there is no dynamic code where the user inputs could be evaluated and escape out of the expected code flow. Unless your code snippet is generated somewhere else, or one of the column names is really a function that calls dynamic SQL, your code looks safe.
You used the phrase "sanitize the inputs", which is terrible advice for database programming. As much as I love the comic strip XKCD, Randall got this one wrong.
Bind variables are the best solution to avoiding SQL injection. I'll take this opportunity to (poorly) change his comic:
I'm trying to use db2 pl/sql script giving a template code.
--#set delimiter !
begin atomic
for S as
<query statement that finds quests, "swaps", with a donor/donation & recipient pair>
do
<update statement that fixes Loot with the swap 'S'>;
end for;
-- handle each swap
end!
-- we're done once through
in my query statement i used something like this:
with
t1 (args) as (
...
)
...
select ...
where ... ;
in the update statement
update Loot set ... where ...
but the problem is, when i try to run the full sql code script on the database, I keep getting the message :
"An unexpected token "begin" was found following "<identifier>".
Expected tokens may include: "USER". SQLSTATE=42601 DB21007E End of file
reached while reading the command.
I want to know, how to use the proper syntax or format to include the "with queries" and also update statement to stop giving me the error. I have the "with query" working in a separate file, but when i combine both statements into the template, it would give me this error. Also as well, if I were to include triggers, which part of the code should i put it in. Thank you.
Here is an example that might help.
CREATE TABLE EG(I INT, J INT)!
INSERT INTO EG VALUES (1,1),(2,3)!
begin
for c as with w(i,u) as(values (2,5)) select i,u from w
do
update eg set j = j + c.u where i = c.i;
end for;
end
!
If this does not help your problem, please post a version of your code that we can run and which returns the error message that you are struggling with.
Every time I try to run my database script I reach the last few lines that have my 2 triggers and my script stops after compiling the first trigger.
These are the 2 triggers I have and it compiles "Player Round Trigger" and then the script stops and doesn't reach my second trigger "Handicap Trigger"
--
-- Player Round Trigger
--
CREATE TRIGGER playerRoundUpdateAudit BEFORE UPDATE ON PlayerRound
FOR EACH row BEGIN
INSERT INTO PlayerRoundAudit(old_data_PlayerID, old_data_RoundID, old_data_Holenumber, old_data_holeScore,
new_data_PlayerID, new_data_RoundID, new_data_Holenumber, new_data_holeScore, tbl_name)
VALUES (OLD.playerID, OLD.roundID, OLD.holeNumber, OLD.holeScore, NEW.playerID, NEW.roundID, NEW.holeNumber, NEW.holeScore, "PlayerRound");
END;
/
--
-- Handicap Trigger
--
CREATE TRIGGER handicapUpdateAudit BEFORE UPDATE ON Handicap
FOR EACH row BEGIN
INSERT INTO HandicapAudit(old_data_handicapID, old_data_playerID, old_data_handicapDate, old_data_handicapScore,
new_data_handicapID, new_data_playerID, new_data_handicapDate, new_data_handicapScore, tbl_name)
VALUES (OLD.handicapID, OLD.playerID, OLD.handicapDate, OLD.handicapScore, NEW.handicapID, NEW.playerID, NEW.handicapDate, NEW.handicapScore, "Handicap");
END;
/
I'm running the script in Oracle SQL Developer version 4.1.2.20 (the newest one atm)
Acturlly the first triggers compiles with errors, and breaks the script.
You can do an experiment - change a header of first trigger into CREATE OR REPLACE TRIGGER ....,
then in SQL Developer click on the first trigger to move cursor into it's code, then press Ctrl-Enter - this executes one statement where the cursor is placed (actually - 'CREATE` statement of the first trigger).
Then examine "Compiler log" window - you will see a message like this:
There are two problems with this trigger:
you are using OLD.column_name and NEW.column_name, what is wrong. You need use :OLD.column_name and :NEW.column_name, using a colon as a prefix
you are using double quotes instead of quotes here: "PlayerRound", and Oracle doesn't interpret this as a string, but as an identifier (of variable, column name etc.). Use 'PlayerRound' within quotes instead.
Change the first trigger like below an it should compile:
set define off
CREATE or replace TRIGGER playerRoundUpdateAudit BEFORE UPDATE ON PlayerRound
FOR EACH row BEGIN
INSERT INTO PlayerRoundAudit(old_data_PlayerID, old_data_RoundID,
old_data_Holenumber, old_data_holeScore,
new_data_PlayerID, new_data_RoundID, new_data_Holenumber,
new_data_holeScore, tbl_name)
VALUES (:OLD.playerID, :OLD.roundID, :OLD.holeNumber, :OLD.holeScore,
:NEW.playerID, :NEW.roundID, :NEW.holeNumber, :NEW.holeScore, 'PlayerRound');
end;
/
You need also correct the second trigger, because it contains similar errors.
Remark : put SET DEFINE OFF into the script to turn off a variable substitution, otherwise SQL-Developer will prompt to enter a value for each :NEW and :OLD
I'm not so familiar with Oracle SQL Developer but is there an option to run the script as "Execute as script"? This feature is available on TOAD...
This is the error I get when I run the code below. I'm not too sure what's wrong any help is appreciated
procedure TFSearchMember.btnSearchClick(Sender: TObject);
var buttonSelected:integer;
WhereTextSelection,WhereFieldSelection:string;
begin
WhereFieldSelection:=cboWhereField.Text;
WhereTextSelection:=txtWhere.Text;
adoQuery1.Parameters[0].Value:=WhereTextSelection;
adoQuery1.Open;
ADOQuery1.Requery;
txtWhere.Text:='';
cboWhereField.Text:='';
if ADOQuery1.RecordCount=0 then
begin
buttonSelected:=MessageDlg('Record not found.', mtError, [mbOK],0);
if buttonSelected = mrOK then
Exit;
end;
I also have this in the ADOQuery SQL property
Although your question doesn't say so, I'd suspect that you're trying to allow the user to both select the field to use in the WHERE (from cboWhereField) and the value (from txtWhere). If that's the case, you have to update the SQL first before you can assign the parameter, as both are changing.
Something like this should work (in a basic sense):
procedure TFSearchMember.btnSearchClick(Sender: TObject);
const
SQLBase = 'SELECT * FROM tblMembers WHERE %s = :SearchValue';
begin
if AdoQuery1.Active then
AdoQuery1.Close;
AdoQuery1.SQL.Text := Format(SQLBase, [cboWhereField.Text]);
AdoQuery1.Parameters.ParamByName('SearchValue').Value := txtWhere.Text;
AdoQuery1.Open;
txtWhere.Text:='';
cboWhereField.Text:='';
if not ADOQuery1.IsEmpty then
begin
// No need for if test here, as you're only offering one value.
// MessageDlg can't return anything other than mrOK
MessageDlg('Record not found.', mtError, [mbOk], 0);
Exit;
end;
// Your other code
end;
I assume that not all code is shown, because it seems that you try to create dynamic SQL where the "WhereFieldSelection" can be changed to whatever is shown in the combobox. If you change the SQL.Text property (e.g. to use "Forename") of the ADOQuery AFTER the parameter value is set, the value of the parameter is lost, and you will have to reset it. Also, the Requery, is not necessary, as Ken White mentioned.
I am calling a stored procedure from my Groovy code. The stored proc looks like this
SELECT * FROM blahblahblah
SELECT * FROM suchAndsuch
So basically, two SELECT statements and therefore two ResultSets.
sql.eachRow("dbo.testing 'param1'"){ rs ->
println rs
}
This works fine for a single ResultSet. How can I get the second one (or an arbitrary number of ResultSets for that matter).
You would need callWithAllRows() or its variant.
The return type of this method is List<List<GroovyRowResult>>.
Use this when calling a stored procedure that utilizes both output
parameters and returns multiple ResultSets.
This question is kind of old, but I will answer since I came across the same requirement recently and it maybe useful for future reference for me and others.
I'm working on a Spring application with SphinxSearch. When you run a query in sphinx, you get results, you need to run a second query to get the metadata for number of records etc...
// the query
String query = """
SELECT * FROM INDEX_NAME WHERE MATCH('SEARCHTERM')
LIMIT 0,25 OPTION MAX_MATCHES=25;
SHOW META LIKE 'total_found';
"""
// create an instance of our groovy sql (sphinx doesn't use a username or password, jdbc url is all we need)
// connection can be created from java, don't have to use groovy for it
Sql sql = Sql.newInstance('jdbc:mysql://127.0.0.1:9306/?characterEncoding=utf8&maxAllowedPacket=512000&allowMultiQueries=true','sphinx','sphinx123','com.mysql.jdbc.Driver')
// create a prepared statement so we can execute multiple resultsets
PreparedStatement ps = sql.getConnection().prepareStatement(query)
// execute the prepared statement
ps.execute()
// get the first result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs1 = new GroovyResultSetExtension(ps.getResultSet())
rs1.eachRow {
println it
}
// call getMoreResults on the prepared statement to activate the 2nd set of results
ps.getMoreResults()
// get the second result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs2 = new GroovyResultSetExtension(ps.getResultSet())
rs2.eachRow {
println it
}
Just some test code, this needs some improving on. You can loop the result sets and do whatever processing...
Comments should be self-explanatory, hope it helps others in the future!