Delphi - combo box search in database using sql queries - sql

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.

Related

the insert parameter of a checkbox status in an insert query

How do I check the status of a checkbox (checked or not checked) on my Form and then pass it on to my SQL insert query?
I've got the parameter in my stored procedure:
#p6 bit
However, in Delphi is the problem :
DataModule7.SP_INSERT.ParamByName('p6').AsBoolean := cxCheckbox1.Properties; //???
Does someone know how to do this?
What you need is
DataModule7.SP_INSERT.ParamByName('p6').AsBoolean := cxCheckbox1.Checked;
Assuming you are executing this code from the Form containing cxCheckBox1.

How to prevent SQL Injection in PL/SQL

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:

Why keeps returning me the ORA-01403 error?

Hello guys when I'm running my code in a query everything seems to walk fine, but when I put it within a stored procedure it returns me the 'No data found error'.
I used an exception handling error but it returns me the same error.
create or replace procedure test(i_d number)
as
l_text VARCHAR(900);
begin
select 'TEST, '||to_char(D3,'yy.mm.dd')|| CHR(10)||'STRINGTEXT'||D2
into l_text
from table
where id = i_d;
EXCEPTION
WHEN no_data_found THEN
-- do something
dbms_output.put_line('No records found for employee no ');
end;
what can I do?
Can you explain the whole part of what you are doing "--do something" inside your exception part ? the only way I see is an error could be raised inside the Exception part which would ideally through the error.
Can you provide the sample table structure and data set to test this scenario. It would be great if you could share a livesql link so that we could help you out.
You can use LiveSQL - https://livesql.oracle.com/apex/f?p=590:1000
Also can you try to change the select statement as below, and try to run the proc to make sure its not due to the to_char function.
select 'TEST, '|| D3 || CHR(10)||'STRINGTEXT'||D2 into l_text
try replacing to_varchar(D3,'yy.mm.dd') with to_char(D3,'yy.mm.dd')

Scope of SQL query in multiple instances of a form

I have a form that I open multiple instances of. In there I use a SQL query to read some data from a database (Absolute Database in this case). I then fill out a few variables with data and also use the query for other operations during the lifetime of the form.
The problem is that when I open more than one instance of the form, the data change on the old forms to values from the last opened form.
I create the query in the form when it's opened so I thought that they wouldn't share the same data.
I don't use auto-created forms.
How can avoid this from happening?
** Edit - Added some code **
I create the form as follows:
procedure TfrmMain.OpenFormsFunction(Sender: TObject);
var
Resultater: TfrmregResultat;
begin
// Some code for checking if forms are already open
// Locate record in table to be used as paramdata in the query in the newly opened form
DataX.tStevneHead.Locate('StevneNummer;GrenType', VarArrayOf([StevneNummer, GrenType), []);
Resultater := TfrmRegResultat.Create(nil);
Resultater.Show; // OnClose action for the form is caFree
end;
Snip from the form's code
// decleared in implementation
Dato: TDate;
GrenType: string;
GrenRunder: integer;
MaxPoeng: integer;
procedure TfrmRegResultat.FormShow(Sender: TObject);
begin
//-- qStevneHead is a TABSQuery component on the form
//-- DataX is the name of my DataModule
with qStevneHead do
begin
Close;
SQL.Clear;
SQL.Text := 'SELECT * FROM StevneHead WHERE GrenType = :aGrenType AND StevneNummer = aStevneNummer';
ParamByName('aGrenType').AsString := DataX.tStevneHead.FieldByName('GrenType').Value;
ParamByName('aStevneNummer').AsString := DataX.tStevneHead.FieldByName('StevneNummer').Value;
Open;
end;
GrenRunder := qStevneHead.FieldByName('AntallRunder').Value;
Dato := qStevneHead.FieldByName('Dato').AsDateTime;
GrenType := qStevneHead.FieldByName('GrenType').Value;
MaxPoeng := qStevneHead.FieldByName('MaxPoeng').Value;
// More code to init stringgrid and other stuff on the form
end;
The problem seems to be that you're using global variables. Change them to be fields of the form and your problem should be solved. IOW, now you have
implementation
var
Dato: TDate;
GrenType: string;
GrenRunder: integer;
MaxPoeng: integer;
Change it to
type
TfrmRegResultat = class(...)
...
private
Dato: TDate;
GrenType: string;
GrenRunder: integer;
MaxPoeng: integer;
...
end;
If you need to access the values from some other part of the program (ie in the main form) then make them public propertyes or fields and access them via the currently active form variable.

Oracle SQL Developer how to see output of a sp

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;