So I've made a button in my program that's supposed to clear all the tables in my database but it gives an error when clicking on the button in run-time. How do I remove that error?
Code I'm using:
ClearDB button's code
procedure TfrmEntry.bmbClearDBClick(Sender: TObject);
var
i:integer;
begin
i:=MessageDlg('Are you sure you want to clear the Racers database? (all current data in the database will be lost.)',mtWarning,[mbOK,mbCancel],0);
if i = mrOk then
begin
//clears entire database
with dmRacers do
begin
tbl1660.DeleteRecords(arAll);
tblXKarts.DeleteRecords(arAll);
tblTwoPointOne.DeleteRecords(arAll);
tblMidB.DeleteRecords(arAll);
tblMidA.DeleteRecords(arAll);
tblLateModel.DeleteRecords(arAll);
tblSprints.DeleteRecords(arAll);
tblV8.DeleteRecords(arAll);
tblHeavyMetals.DeleteRecords(arAll);
tblHotrods.DeleteRecords(arAll);
tblPinkrods.DeleteRecords(arAll);
tblStockrods.DeleteRecords(arAll);
tblMinis.DeleteRecords(arAll);
tblDevelopment.DeleteRecords(arAll);
end;
end
else
begin
i:=MessageDlg('Clear aborted',mtInformation,[mbOk],0);
end;
end;
Entry button's code
procedure TfrmEntry.btnEntryClick(Sender: TObject);
var
sRacerName,sLicence,sCarNum:string;
iNum:integer;
begin
//saves input (works perfectly)
sCarNum:=edtCarNumber.Text;
sRacerName:=edtRacerName.Text;
sLicence:=edtLicenseNum.Text;
//ifs for saving input to the db
if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = '1660s' then
begin
with dmRacers do
begin
tbl1660.insert;
tbl1660['Car Number']:=sCarNum;
tbl1660['Racer Name']:=sRacerName;
tbl1660['Licence']:=sLicence;
tbl1660.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = '2.1s' then
begin
with dmRacers do
begin
tblTwoPointOne.insert;
tblTwoPointOne['Car Number']:=sCarNum;
tblTwoPointOne['Racer Name']:=sRacerName;
tblTwoPointOne['Licence']:=sLicence;
tblTwoPointOne.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Crosskarts' then
begin
with dmRacers do
begin
tblXKarts.insert;
tblXKarts['Car Number']:=sCarNum;
tblXKarts['Racer Name']:=sRacerName;
tblXKarts['Licence']:=sLicence;
tblXKarts.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Heavy Metals' then
begin
with dmRacers do
begin
tblHeavyMetals.insert;
tblHeavyMetals['Car Number']:=sCarNum;
tblHeavyMetals['Racer Name']:=sRacerName;
tblHeavyMetals['Licence']:=sLicence;
tblHeavyMetals.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Hotrods' then
begin
with dmRacers do
begin
tblHotrods.insert;
tblHotrods['Car Number']:=sCarNum;
tblHotrods['Racer Name']:=sRacerName;
tblHotrods['Licence']:=sLicence;
tblHotrods.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Midgets A' then
begin
with dmRacers do
begin
tblMidA.insert;
tblMidA['Car Number']:=sCarNum;
tblMidA['Racer Name']:=sRacerName;
tblMidA['Licence']:=sLicence;
tblMidA.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Midgets B' then
begin
with dmRacers do
begin
tblMidB.insert;
tblMidB['Car Number']:=sCarNum;
tblMidB['Racer Name']:=sRacerName;
tblMidB['Licence']:=sLicence;
tblMidB.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Minis' then
begin
with dmRacers do
begin
tblMinis.insert;
tblMinis['Car Number']:=sCarNum;
tblMinis['Racer Name']:=sRacerName;
tblMinis['Licence']:=sLicence;
tblMinis.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Pinkrods' then
begin
with dmRacers do
begin
tblPinkrods.insert;
tblPinkrods['Car Number']:=sCarNum;
tblPinkrods['Racer Name']:=sRacerName;
tblPinkrods['Licence']:=sLicence;
tblPinkrods.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Sprints' then
begin
with dmRacers do
begin
tblSprints.insert;
tblSprints['Car Number']:=sCarNum;
tblSprints['Racer Name']:=sRacerName;
tblSprints['Licence']:=sLicence;
tblSprints.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Stockrods' then
begin
with dmRacers do
begin
tblStockrods.insert;
tblStockrods['Car Number']:=sCarNum;
tblStockrods['Racer Name']:=sRacerName;
tblStockrods['Licence']:=sLicence;
tblStockrods.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'SWD Development' then
begin
with dmRacers do
begin
tblDevelopment.insert;
tblDevelopment['Car Number']:=sCarNum;
tblDevelopment['Racer Name']:=sRacerName;
tblDevelopment['Licence']:=sLicence;
tblDevelopment.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'V8s' then
begin
with dmRacers do
begin
tblV8.insert;
tblV8['Car Number']:=sCarNum;
tblV8['Racer Name']:=sRacerName;
tblV8['Licence']:=sLicence;
tblV8.Post;
end;
end
else if cbxGridSelect.Items[cbxGridSelect.ItemIndex] = 'Late Models' then
begin
with dmRacers do
begin
tblLateModel.insert;
tblLateModel['Car Number']:=sCarNum;
tblLateModel['Racer Name']:=sRacerName;
tblLateModel['Licence']:=sLicence;
tblLateModel.Post;
end;
end;
end;
Data module's code
const
scConnectionString = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%pathtomdb%Racers.mdb;Mode=ReadWrite;Persist Security Info=False;';
procedure TdmRacers.DataModuleCreate(Sender: TObject);
var
path:string;
begin
path:=ExtractFilePath(ParamStr(0));
conToDB.ConnectionString := StringReplace(scConnectionString, '%pathtomdb%', path, []);
conToDB.Connected:=True;
tbl1660.Active := True;
tblXKarts.Active := True;
tblTwoPointOne.Active := True;
tblMidB.Active := True;
tblMidA.Active := True;
tblLateModel.Active := True;
tblSprints.Active := True;
tblV8.Active := True;
tblHeavyMetals.Active := True;
tblHotrods.Active := True;
tblPinkrods.Active := True;
tblStockrods.Active := True;
tblMinis.Active := True;
tblDevelopment.Active := True;
end;
Error I'm recieving:
Thanks in advance for all the help!Kind RegardsPrimeBeat
From a 2005 thread in borland.public.delphi.database.ado:
http://www.devsuperpage.com/search/Articles.asp?ArtID=877427
PROBLEM:
I am trying to delete all records from a TADOTable. I am
using the following line of code:
tblInvoices.DeleteRecords(arAll);
But it gives an error message: "Operation is not allowed in this
context".
Any idea what might be causing this?
CAUSE:
Unfortunately Microsoft never implemented that option for DeleteRecords.
You will need to use a Delete query.
SOLUTION:
Instead of using the DeleteRecords, use a routine like this:
CabInfo.Active := true;
MyCmd.CommandText := 'Delete * from CabInfo';
MyCmd.Execute;
CabInfo.Active := false;
where CabInfo is your table name.
Related
The following code is a sub-part of a bigger code where the array modify_column_list is declared and includes the column names of the table beset_e_szerepmatrix.
declare
cursor v_cur is select * from delta_stage.beset_e_szerepmatrix;
v_rec delta_stage.beset_e_szerepmatrix%rowtype;
begin
open v_cur;
loop
fetch v_cur into v_rec;
exit when v_cur%notfound;
v_sql := null;
for i in 1..modify_column_list.count loop
if v_sql is null and v_rec.modify_column_list(i) = 0 then
v_sql := modify_column_list(i);
else
if v_sql is not null and v_rec.modify_column_list(i) = 0 then
v_sql := v_sql || ', ' || v_rec.modify_column_list(i);
end if;
end if;
end loop;
v_rec.adathianyos_mezo := v_sql;
end loop;
close v_rec;
end;
Every columns include 0 or 1 value in the table beset_e_szerepmatrix. In the column adathianyos_mezo should include all column names, where the record has 0 value. How can I use the modify_column_list(i) in the cursor?
Getting error while using two cursors
[Error] PLS-00103 (45: 48): PLS-00103: Encountered the symbol
"TX_COM_LOCATION" when expecting one of the following:
:= . ( # % ;
The symbol ":=" was substituted for
"TX_COM_LOCATION" to continue.
Please help
CREATE OR REPLACE PROCEDURE COM_LOCATION_TXM
IS
BEGIN
DECLARE CURSOR TXM_COM_LOCATION IS SELECT col1,col2,col3 from TBL_SAR_SALAS_1 A;
CURSOR TX_COM_LOCATION is select col1,col2,col3 from TBL_LOCALES B;
TMP_TXM TXM_COM_LOCATION%ROWTYPE;
TMP_TXM TX_COM_COCATION%ROWTYPE;
Begin
IF NOT TXM_COM_LOCATION%ISOPEN
THEN OPEN TXM_COM_LOCATION;
END IF;
FETCH TXM_COM_LOCATION INTO TMP_TXM;
EXIT
WHEN TXM_COM_LOCATION%NOTFOUND;
IF NOT TX_COM_LOCATION%ISOPEN
THEN
OPEN TXCOM_LOCATION;
END IF;
LOOP FETCH TX_COM_LOCATION INTO TMP_TX; EXIT WHEN TX_COM_LOCATION%NOTFOUND;
BEGIN Insert statement()
END;
END LOOP;
END LOOP;
commit;
END;
END COM_LOCATION_TXM ;
Check this:
CREATE OR REPLACE PROCEDURE COM_LOCATION_TXM IS BEGIN DECLARE CURSOR TXM_COM_LOCATION IS SELECT col1, col2, col3 FROM TBL_SAR_SALAS_1 A; CURSOR TX_COM_LOCATION IS SELECT col1, col2, col3 FROM TBL_LOCALES B; TMP_TXM TXM_COM_LOCATION%ROWTYPE; TMP_TXM TX_COM_LOCATION%ROWTYPE; BEGIN IF NOT TXM_COM_LOCATION%ISOPEN THEN OPEN TXM_COM_LOCATION; END IF; LOOP FETCH TXM_COM_LOCATION INTO TMP_TXM; EXIT WHEN TXM_COM_LOCATION%NOTFOUND; IF NOT TX_COM_LOCATION%ISOPEN THEN OPEN TXCOM_LOCATION; END IF; LOOP FETCH TX_COM_LOCATION INTO TMP_TX; EXIT WHEN TX_COM_LOCATION%NOTFOUND; BEGIN NULL; -- REPLACE NULL WITH INSERT STATEMENT END; END LOOP; END LOOP; COMMIT; END; END COM_LOCATION_TXM;
I have this store procedure and I lets assume the user want to update some fields not all of it, what should I add on the update section
CREATE PROCEDURE [dbo].[helpChainAllCRUD]
#action char(1),
#lineId char(2),
#lineShift smallint = NULL,
#sequence smallint = NULL,
#Role VARCHAR(32) = NULL,
#radioChannel VARCHAR(16)= NULL,
#officePhone VARCHAR(16)= NULL,
#cellPhone VARCHAR(16)= NULL
as
IF(#action = 'I')
BEGIN TRY
BEGIN TRAN
INSERT INTO [dbo].[tbl_helpChain] (lineId,lineShift,sequence,Role,radioChannel,officePhone,cellPhone)
VALUES (#lineId ,#lineShift,#sequence,#Role,#radioChannel,#officePhone,#cellPhone)
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT >0
ROLLBACK
END CATCH
IF(#action = 'U')
BEGIN TRY
BEGIN TRAN
UPDATE [dbo].[tbl_helpChain] SET lineShift=#lineShift,sequence=#sequence,Role=#Role,radioChannel=#radioChannel,officePhone=#officePhone,cellPhone=#cellPhone WHERE lineId=#lineId
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT >0
ROLLBACK
END CATCH
IF(#action = 'D')
BEGIN TRY
BEGIN TRAN
Delete from [dbo].[tbl_helpChain] WHERE lineId=#lineId
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT >0
ROLLBACK
END CATCH
IF(#action = 'S')
Begin
select lineId,lineShift,sequence,Role,radioChannel,officePhone,cellPhone from [dbo].[tbl_helpChain]
end
GO
I'm sure there are much better solutions, but a quick and easy solution might be to use very ugly dynamic SQL
DECLARE #QueryText nvarchar(max) = 'UPDATE [dbo].[tbl_helpChain] SET '
IF #radioChannel<> NULL
#QueryText = #QueryText + 'RadioChannel=#radioChannel'
EXECUTE SP_EXECUTESQL #QueryText
If i.e. null means don't update you could simply write
SET lineShift = COALESCE(#lineShift,lineShift), ...
or you take another special value and a case-expression
SET lineShift = CASE WHEN #lineShift = -1 then lineShift else #lineShift end,
or you give extra boolean parameters for each column for use in the case-expression
UPDATE helpChain
SET
fullName = ISNULL(#fullName,fullName),
lineShift = ISNULL(#lineShift,lineShift),
sequence = ISNULL(#sequence,sequence),
Role = ISNULL(#Role,Role),
radioChannel = ISNULL(#radioChannel,radioChannel),
officePhone = ISNULL(#officePhone,officePhone),
cellPhone = ISNULL(#cellPhone,cellPhone)
WHERE lineId = #lineId
I try to use BEGIN-END liberally. Is there a point in using this contruct in this context?:
BEGIN TRY
BEGIN
--do x
--do y
END
END TRY
BEGIN CATCH
BEGIN
--do z
END
END CATCH;
Or is it just as safe to use the following?:
BEGIN TRY
--do x
--do y
END TRY
BEGIN CATCH
--do z
END CATCH;
A begin try ... end try block is a complete block in itself, there is no point in having an extra begin ... end inside it.
Use begin ... end for statements that aren't blocks in themselves, for example if:
if ... begin
...
end else begin
...
end
I need to execute a store procedure from another with the common EXEC command.
I need to be sure, that all the sql statements will be under transaction.
BEGIN TRANSACTION
BEGIN TRY
SET #Esercizio = (SELECT ESERCIZIO_OBIETTIVI_CONSUNTIVARE from TB_SCHEDE WHERE MATRICOLA = #iMATRICOLA and COD_VALUTAZIONE = #iCOD_VALUTAZIONE)
SET #TipoProcesso = (SELECT ISNULL(TipoProcesso, 'middle') from TB_SCHEDE WHERE MATRICOLA = #iMATRICOLA and COD_VALUTAZIONE = #iCOD_VALUTAZIONE)
DELETE FROM TB_SCHEDE WHERE MATRICOLA = #iMATRICOLA and COD_VALUTAZIONE = #iCOD_VALUTAZIONE
DELETE FROM TB_SCHEDE_AUTOVAL WHERE MATRICOLA = #iMATRICOLA and COD_VALUTAZIONE = #iCOD_VALUTAZIONE
DELETE FROM TB_OBIETTIVI WHERE MATRICOLA = #iMATRICOLA and ESERCIZIO = #Esercizio
DELETE FROM TB_OBIETTIVI_AUTOVAL WHERE MATRICOLA = #iMATRICOLA and ESERCIZIO = #Esercizio
EXEC AnotherStore #iCOD_VALUTAZIONE, #iMATRICOLA, #TipoProcesso
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
If the AnotherStore procedure throw an exception, does the DB engine ensure rollback from the caller store procedure?
Hope to be clear.
See Exception handling and nested transactions for an example of execption handling in the presence of transactions:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare #trancount int;
set #trancount = ##trancount;
begin try
if #trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if #trancount = 0
commit;
end try
begin catch
declare #error int, #message varchar(4000), #xstate int;
select #error = ERROR_NUMBER(), #message = ERROR_MESSAGE(), #xstate = XACT_STATE();
if #xstate = -1
rollback;
if #xstate = 1 and #trancount = 0
rollback
if #xstate = 1 and #trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, #error, #message) ;
end catch
end
The simple answer is yes it will rollback the changes for the caller stored procedure, but think it through if you have transactions inside the other stored procedure, there are possibilities for things not behaving as you expect if that is the case. A ROLLBACK will affect ALL of the transactions, although this is probably what you want. You can use ##TRANCOUNT within your catch and determine if you want to rollback the entire thing, and Savepoints.
Everything you do to the database between the BEGIN TRANSACTION and COMMITor ROLLBACK is part of the transaction, and if any lines get an error, control will be routed to the CATCH block where the transaction will be rolled back. Things like table variables would fall outside of this scope and not get rolled back. And as #David Brabant said, BEGIN TRANSACTION should be in the BEGIN TRY block.