How to update a null value in a column - Microsoft Visual Studio - visual-studio-2010

--Create sample table for illustration of issue
CREATE TABLE SAMPLETABLE (
[Order_ID] int,
[Individual_ID] int,
[SAMPLECOLUMN] varchar(50),
[FACILITY] int,
[ORDERCODE] int
)
GO
--Populate column with values including null for sample column
INSERT INTO
SELECT
TABLEX.TABLE_ID AS [Individual_ID],
TABLEX.ORDER_ID AS [Order_ID],
NULL AS [SAMPLECOLUMN],
TABLEX.FACILITY_ID AS [FACILITY],
TABLEX.ORDERCODE AS [ORDERCODE]
FROM TABLEX
--UPDATE NULL values of SAMPLECOLUMN with string values
UPDATE SAMPLETABLE
SET
SAMPLETABLE.SAMPLECOLUMN = CASE WHEN SAMPLETABLE.ORDERCODE IN ('1') THEN 'THISWILLBETHESTRING'
END
FROM SAMPLETABLE
WHERE SAMPLETABLE.SAMPLECOLUMN IS NULL
What I am trying to do is to replace the null values that I initially populated my table with using the update statement. I receive the error: 'Conversion failed when converting the varchar value 'THISWILLBETHESTRING' because null has a data type of int, whereas the values that I want to use to update it are string. Keep in mind that in the update statement the SAMPLETABLE.ORDERCODE comes from the same table that I am updating.
Here is the DDL to illustrate the issue:
-- DDL and sample data, start
DECLARE #start TABLE
(ID INT IDENTITY PRIMARY KEY,
data VARCHAR(20) NULL,
ordercode int);
INSERT INTO #start ([data], [ordercode])
VALUES
(NULL, '1')
,(NULL, '1')
,(NULL, '2');
-- DDL and sample data, end
SELECT *
FROM #start;
DECLARE #end TABLE
(ID INT IDENTITY PRIMARY KEY,
data VARCHAR(20) NULL,
ordercode int);
INSERT INTO #end ([data], [ordercode])
VALUES
('STRINGVALUEIWANT', '1')
,('STRINGVALUEIWANT', '1')
,('ANOTHERSTRING', '2');
-- DDL and sample data population, end
SELECT *
FROM #end;

Related

How to optional update data on oracle?

i have this table:
CREATE TABLE "ALMAT"."PRODUCT"
( "ID" NUMBER(*,0) NOT NULL ENABLE,
"NAME" VARCHAR2(50 BYTE),
"PRICE" NUMBER(*,0),
"DESCRIPTION" VARCHAR2(180 BYTE),
"CREATE_DATE" DATE,
"UPDATE_DATE" DATE,
CONSTRAINT "PRODUCT_PK" PRIMARY KEY ("ID"))
i want to update data in this table, this is my stored procedure:
CREATE OR REPLACE PROCEDURE UPDATEPRODUCT(prod_id int, prod_name varchar2 default null, prod_price int default null) AS
BEGIN
update product
set
name = prod_name,
price = prod_price,
update_date = sysdate
where id = prod_id;
commit;
END UPDATEPRODUCT;
im using optional parameters, how can i update only 1 column? for example: only "NAME" or "PRICE".
Use COALESCE (or NVL) to keep the current value when a NULL value is passed in (or the default is used):
CREATE OR REPLACE PROCEDURE UPDATEPRODUCT(
prod_id PRODUCT.ID%TYPE,
prod_name PRODUCT.NAME%TYPE DEFAULT NULL,
prod_price PRODUCT.PRICE%TYPE DEFAULT NULL
)
AS
BEGIN
UPDATE product
SET name = COALESCE(prod_name, name),
price = COALESCE(prod_price, price),
update_date = SYSDATE
WHERE id = prod_id;
END UPDATEPRODUCT;
Also, do not COMMIT in a stored procedure as it prevents you from chaining multiple procedures together in a single transaction and rolling them all back as a block. Instead, COMMIT from the PL/SQL block that calls the procedure.
You can use NVL function here. So your updated procedure would look alike -
CREATE OR REPLACE PROCEDURE UPDATEPRODUCT(prod_id int,
prod_name varchar2 default null,
prod_price int default null) AS
BEGIN
UPDATE product
SET name = NVL(prod_name, name),
price = NVL(prod_price, price),
update_date = sysdate
WHERE id = prod_id;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END UPDATEPRODUCT;

Oracle PLS-00049: bad bind variable

I'm getting this error when I try to create this trigger. I tried everything but I don't know what seems to be the problem.
Here is the code:
CREATE OR REPLACE TRIGGER after_price_update
AFTER UPDATE
ON Item
FOR EACH ROW
DECLARE new_totalprice INT;
BEGIN
IF :OLD.price <> :new.price THEN
new_totalprice := :old.Quantity * :new.price;
INSERT INTO OrderRecord(OrderRecord_Id, Item_Id, Employee_Id, Reservation_Id, Order_Time, Quantity, TotalPrice)
VALUES(old.OrderRecord_Id, old.Item_Id, old.Employee_Id, old.Reservation_Id, old.Order_Time, old.Quantity, new_totalprice);
END IF;
END;
And the error is:
4/22 PLS-00049: bad bind variable 'OLD.QUANTITY'
The tables look like this:
CREATE TABLE Item (
Item_Id int PRIMARY KEY,
Menu_Id int,
Name varchar2(20),
Description varchar2(120),
Price int,
FOREIGN KEY(Menu_Id) REFERENCES Menu(Menu_Id)
);
CREATE TABLE OrderRecord (
OrderRecord_Id int PRIMARY KEY,
Item_Id int,
Employee_Id int,
Reservation_Id int,
Order_Time date,
Quantity int,
TotalPrice int,
FOREIGN KEY(Item_Id)References Item(Item_Id),
FOREIGN KEY(Employee_Id)References Employee(Employee_Id),
FOREIGN KEY(Reservation_Id)References Reservation(Reservation_Id)
);
Table OrderRecord is not the table being updated: you cannot reference an old value for this table; you need to read this value with some SELECT statement.
IF :OLD.price <> :new.price THEN
new_totalprice := <Quantity> * :new.price;
There is no column Quantity in the table ITEM on which you are applying trigger.
If I understand what you are wanting to do correctly, it looks like you want to update the calculated total price of all existing OrderRecord entries when an Item entry has a price change.
CREATE OR REPLACE TRIGGER after_price_update
AFTER UPDATE
ON Item
FOR EACH ROW
BEGIN
IF NVL(:OLD.Price, 0) <> NVL(:new.Price, 0) THEN
-- Update the child table "OrderRecord" for this item using new price
UPDATE OrderRecord SET TotalPrice = Quantity * :new.Price WHERE Item_Id = :new.Item_id;
END IF;
END;
Note that this trigger is on the parent table, Item, and references two values from the modified record: price and Item_Id, to update the child OrderRecord table.
Also note the use of NVL to watch for nulls because the comparison will not succeed if a null is on either side. Using zero for null is debatable; one could use a value that will never occur such as a negative number.

Error "no data foun" on insert in my trigger ORACLE

I've three tables:
create table person(
id_per number(1) primary key not null,
name_per varchar(15) not null);
create table training(
id_training number(1) primary key not null,
start_training date not null,
final_training date not null);
create table training_person(
id_tp number(3) primary key not null,
id_per number(8) not null,
id_training number(1) not null);
I created a trigger whose function is verify that the user can't to insert in the table training_person if the user have a active training ... but when I want to insert a new register but the person don't have any training registered before, oracle show me the following error: "no data found".
This is my trigger:
CREATE OR REPLACE TRIGGER VERIFY_TRAINING
BEFORE INSERT OR UPDATE ON training_person
FOR EACH ROW
DECLARE
GET_FINAL_TRAINING DATE;
GET_START_TRAINING DATE;
BEGIN
select MAX(final_training) into GET_FINAL_TRAINING
from training t join training_person x on t.id_training=x.id_training join person e on e.id_per=x.id_per
WHERE e.id_per=:new.id_per;
select start_training into GET_START_TRAINING
from training t join training_person x on t.id_training=x.id_training
where t.id_training=:new.id_training;
IF (GET_FINAL_TRAINING > GET_START_TRAINING) THEN
RAISE_APPLICATION_ERROR(-20091,'U CANT INSERT TRAINING.');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO training_person values(:new.id_tp,:new.id_per,:new.id_training);
END;
I'm learning Oracle, so I dunno which is the problem. Thanks.

table NISHAN.TBL_ADMIN is mutating, trigger/function may not see it

I have a trigger named tr_admin_user_role that automatically insert values into tbl_user_role table when we perform a insert in another table called tbl_admin. There is no error at compile time but whenever I insert a value into tbl_admin table it shows me an error and error is like
This is my tbl_admin table
CREATE TABLE tbl_admin(
admin_id INTEGER,
username VARCHAR2(50) NOT NULL UNIQUE,
passwords VARCHAR2(50) NOT NULL,
email VARCHAR2(100) UNIQUE,
enabled CHAR(1) DEFAULT 1 NOT NULL,
created_at DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT pk_admin_id PRIMARY KEY(admin_id)
);
tbl_user_role table
CREATE TABLE tbl_user_role(
user_role_id INTEGER,
username VARCHAR2(50) NOT NULL,
user_role VARCHAR2(50) DEFAULT 'ROLE_ADMIN' NOT NULL,
CONSTRAINT pk_user_role_id PRIMARY KEY(user_role_id)
);
Trigger that i have created
CREATE OR REPLACE TRIGGER tr_admin_user_role
AFTER INSERT ON tbl_admin
FOR EACH ROW
DECLARE
new_username TBL_ADMIN.username%TYPE;
BEGIN
SELECT username INTO new_username FROM (
SELECT username FROM tbl_admin ORDER BY username DESC
) WHERE ROWNUM = 1;
INSERT INTO tbl_user_role(username, user_role) VALUES(new_username, 'ROLE_ADMIN');
END;
Insert statement
INSERT INTO tbl_admin(username, passwords) VALUES('nisha', 'nisha');
That's not how you fetch the newly inserted / updated / previous value of a column in a Trigger. You should use the :OLD.column_name and :NEW.column_name to refer the old and new column values.Read the documentation to understand more.
So, your Trigger could be rewritten as
CREATE OR REPLACE TRIGGER tr_admin_user_role AFTER
INSERT ON tbl_admin
FOR EACH ROW
BEGIN
INSERT INTO tbl_user_role (
username,
user_role
) VALUES (
:NEW.username,
'ROLE_ADMIN'
);
END;
/
I assume you are using another trigger to generate
admin_id and user_role_id since they are declared as PRIMARY KEYs
and you are not including them in your inserts.
Db fiddle demo
Here I've used dummy values for those columns.

Returning multiple values after insert

I got this 'Message' table.
CREATE TABLE message (
id INT PRIMARY KEY,
user_id INT NOT NULL REFERENCES users (id) ON DELETE CASCADE,
category_id INT NOT NULL REFERENCES category (id) ON DELETE CASCADE,
text VARCHAR2(4000),
media VARCHAR2(500),
creation_date DATE DEFAULT SYSDATE
);
CREATE SEQUENCE message_seq;
CREATE OR REPLACE TRIGGER message_bir
BEFORE INSERT ON message
FOR EACH ROW
BEGIN
SELECT message_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
After i insert something i need the last inserted id and the date.
INSERT INTO message (user_id, category_id, media)
VALUES (1, 1, 'fdsfsd')
RETURNING id INTO :last_insert_id
The above gives me the last inserted id, but like i said i also need the creation_date. I dont want to do a select query after...
Is there a way to get 2 values back after run an insert?
You can write:
RETURNING id, creation_date INTO :last_insert_id, :last_creation_date.
See http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/returninginto_clause.htm

Resources