Stored Procedure Hit Counter - stored-procedures

I have a table with 3 column's in a table on a MS SQL 2008 Database
ID
ToolID
Count
Can someone toss me a script that will create a stored procedure that accepts the param ToolID and increases its value by 1?
All of my efforts have failed.

try:
CREATE PROCEDURE IncrementToolCount
(
#ToolID int
)
AS
SET NOCOUNT ON
UPDATE Tools_Usage SET [Count]=ISNULL([Count],0)+1 WHERE ToolID=#ToolID
GO

Related

How pass TEXT data type to stored procedure in hana

I'm writing a simple stored procedure for my Hana database, its behavior is to update a table and return the updated element. Here the code:
CREATE OR REPLACE PROCEDURE "UpdateTbl" (in _id integer, in formula text) AS
BEGIN
UPDATE "MyTable" SET "formula" = formula, WHERE "id" = _id;
SELECT "id", "formula" FROM "MyTable" WHERE "id" = _id;
END;
The problem i'm facing is that I cannot specify a TEXT input parameter in stored procedures.
A possible workaround could be to use NVARCHAR instead.
In this way, I can correctly create the stored procedure, but when I run it with 'dummy' value in the NVARCHAR field, i got this error
Error: (dberror) [7]: feature not supported: "Database"."UpdateTbl": ... : Unregistered function name: "to_text
It seems that it cannot convert NVARCHAR in TEXT.
So, there is a way to force the conversion of this kind of parameter in TEXT?
If not, there is a way I'm not considering to pass TEXT parameter as input (other data types, for instance)?
Thnaks in advance
this simple example works as expected when using NVARCHAR or NCLOB as procedure parameter type
DROP TABLE t1;
CREATE TABLE t1 (i int, t text fast preprocess off);
INSERT INTO t1 values(3,'');
INSERT INTO t1 values(4,'');
CREATE OR REPLACE PROCEDURE p1 (in i int, in t nclob) AS
BEGIN
UPDATE t1 SET t = :t WHERE i = :i;
--SELECT i,t FROM t1 where i = :i;
END;
CALL p1(3,'bob went to london');
CALL p1(4,'nancy moved to berlin');
SELECT * FROM t1 WHERE CONTAINS(*,'go',linguistic);
please provide your column properties

Invalid identifier procedure

I'm writing procedure to transfer data from table in one Db named as 'Dev( or testing)' to another table in fdw db where we'll have repository table. Every month, last business day -2, we'll clean data from dev table and transfer it to repository table.
I'm super new to this technology and testing procedure and getting follwiing error
[Error] ORA-00904 (12: 15):
PL/SQL: ORA-00904: "USB"."BAS2_AGENCY_TO_RISKRATE_REPOS"."AS_OF_DATE: invalid identifier
CREATE OR REPLACE PROCEDURE USB.Basel2_riskrating
AS
BEGIN
INSERT INTO USB.BAS2_AGENCY_TO_RISKRATE_REPOS#OFSADEV --INSERTS DATA IN REPOSITORY TABLE
SELECT *
FROM USB.BAS2_AGENCY_TO_RISKRATING_TRAN M
WHERE USB.BAS2_AGENCY_TO_RISKRATE_REPOS.AS_OF_DATE != M.AS_OF_DATE ; --COMPARES DATE COLUMN TO REMOVE DUPLICACY
COMMIT;
END Basel2_riskrating;
Could you please help me in this. Also, it will be great if one could guide me with sample procedure code in wiping data from USB.BAS2_AGENCY_TO_RISKRATING_TRAN table at each month end.
As suggested in the comments, use NOT EXISTS. It's not celar whether you want to check for duplicates in the remote table usb.bas2_agency_to_riskrate_repos#ofsadev or a local version of the same. Use the appropriate table inside NOT EXISTS to do the comparison.
CREATE OR REPLACE PROCEDURE usb.basel2_riskrating AS
BEGIN
INSERT INTO usb.bas2_agency_to_riskrate_repos#ofsadev
SELECT * FROM usb.bas2_agency_to_riskrating_tran m
WHERE NOT EXISTS ( select 1 from
usb.bas2_agency_to_riskrate_repos e --#ofsadev?
where e.as_of_date = m.as_of_date
);
COMMIT; --Try to avoid commits inside procedure, move it to execution section
END basel2_riskrating;
SELECT * FROM USB.BAS2_AGENCY_TO_RISKRATING_TRAN M WHERE USB.BAS2_AGENCY_TO_RISKRATE_REPOS.AS_OF_DATE != M.AS_OF_DATE ;
is wrong. You can not run such a select against DB, it has no USB.BAS2_AGENCY_TO_RISKRATE_REPOS in from clause

Is it possible to add a new column in a stored procedure in db2?

Hi I'm a junior developer, I just want to ask Is it possible to add a new column in a stored procedure in db2? what i mean like an alter table for adding a new column but in stored procedure?
Yes, it's possible but you have to use dynamic sql.
--# SET TERMINATOR #
create table test_add_col(a int) in userspace1#
begin
execute immediate 'alter table test_add_col add b int';
end#
select colname
from syscat.columns
where tabschema=user and tabname='TEST_ADD_COL'#
The result is:
COLNAME
--
A
B

DB2 Stored Procedure: Declare an internal "rowset"

I'm migrating some procedures from PostgreSQL to a new DB2 environment. I've got most of it done but I can't find a way to DECLARE a variable for an internal rowset/record.
Basically what the procedure does on Postgres is this:
DECLARE
counts RECORD;
BEGIN
-- fill "counts" with one row of aggregated data
SELECT
COUNT(....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
INTO counts
FROM (...)
-- check "counts" with some conditionals
IF counts.failed_inserts > 0
(...)
END IF;
(...)
-- return info depending on the data
RETURN (...);
END
I can't find an equivalent to declaring "counts" in the IBM manuals or elsewhere online. The row I need is static (3 columns of aggregated data). So it would be enough to declare that row hardcoded if that is possible.
Is it possible to DECLARE a record / dataset / "virtual table" within a Stored Procedure on the DB2?
We're using DB2 for Linux (V10.5) not DB2 for iSeries.
#mustaccio's answer points to the correct solution:
Outside of the procedure create the needed rowtype:
CREATE TYPE empRow AS ROW (failed_inserts INTEGER, failed_updates INTEGER, failed_deletes INTEGER);
Then you can DECLARE the new type within the procedure
DECLARE newRow empRow;
Not sure I fully understand what you want, but may be you're looking for the ROW data type? Something like this:
DECLARE
TYPE counts_row AS ROW (
failed_inserts INT,
failed_updates INT,
failed_deletes INT
);
counts counts_row;
BEGIN
-- fill "counts" with one row of aggregated data
SELECT
COUNT(....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
INTO counts
FROM (...);
...
PS. Not tested.
More info in the manual.
In lieu of creating a permanent** user defined type that is more or less specific to a single query, you can also achieve the same by using the FOR statement:
FOR counts AS c1 CURSOR FOR SELECT COUNT(.....) AS failed_inserts,
COUNT(....) AS failed_updates,
COUNT(....) AS failed_deletes,
FROM (...)
DO
IF counts.failed_inserts > 0 THEN
(....)
END IF;
END FOR;
** Permanent meaning something that's defined in the system catalog.

Custom sort order for dataset after executing query?

I want the result set of a database query to have a certain order. The information I want to order by is not contained in the database, but dynamically generated in code (so I cannot use ORDER BY).
Is there a way to sort a dataset after executing the database query? (I don't need indexed access but only want to iterate over all records.)
With a ClientDataset you are able to change the order after executing.
Settings IndexFieldNames sorts the dataset.
You can find information here how to connect a clientdataset to another dataset in the same application.
object DataSetProvider1: TDataSetProvider
DataSet = MyAdsQuery
Left = 208
Top = 88
end
object ClientDataSet1: TClientDataSet
Aggregates = <>
Params = <>
ProviderName = 'DataSetProvider1'
Left = 296
Top = 88
end
There is a possibility that shares similarities with Jens' answer (+1) but gets to the result in a slightly different fashion.
Given an existing table:
create table somedata (id integer, name char(20));
insert into somedata values ( 1, 'Tim' );
insert into somedata values ( 2, 'Bob' );
insert into somedata values ( 3, 'Joe' );
If you know the desired short order (either by processing the table or some query result from it), create a temp table that has some key value to match the desired rows from the original table and then the sort order data:
create table #sortorder( id integer, sortvalue integer );
Set the sortvalue field in the temp table to contain the desired order (it could be any sortable data type - doesn't have to be integer):
insert into #sortorder values ( 1, 15 );
insert into #sortorder values ( 2, 12 );
insert into #sortorder values ( 3, 5 );
Then generate the results with a join against the table that provides the sort order:
select sd.* from somedata sd, #sortorder so
where sd.id = so.id
order by so.sortvalue;
AFAIK the only reliable way to sort a dataset is to use ORDER BY.
I would:
Add a dummy order_tag field to your query.
Dump the results to temporary table.
Declare a cursor to iterate over the temporary table and set the order_tag using your custom logic and UPDATE #temp_table statements.
Select the data from the temporary table and order by the tag field.
The main trick here would be to use an Internal calc field (FieldKind = fkInternalCalc) if they are supported by your TDataset sub-class. If they aren't, use a TClientDataset as an intermediate.
DFM:
object ClientDataSet1SortField: TIntegerField
FieldKind = fkInternalCalc
FieldName = 'SortField'
end
pas:
procedure TForm1.FormCreate(Sender: TObject);
begin
ADOConnection1.Open('dbuser', 'Hunter2');
ClientDataSet1.SetProvider(ADOQuery1); // set ClientDataset provider. This will create a TLocalAppServer provider "in the background"
ClientDataSet1.Open;
randomize;
while not ClientDataSet1.Eof do
begin
ClientDataSet1.edit;
ClientDataSet1SortField.AsInteger := random(100);
// as ClientDataSet1SortField is fkInternalCalc it doesn't need to be in the query result set, but can be assigned and used for sorting
ClientDataSet1.Post;
ClientDataSet1.Next;
end;
clientdataset1.IndexFieldNames := 'SortField';
end;

Resources