How do you delete rows specified from an object in oracle? - sql

I have a drop down box on a page in my oracle apex application, I'd like to use the drop down box which displays a company's data(company name) within the company table (which I have achieved); which the user can use to identify specifically what company they'd like to delete. I'd then like to use a button to delete the selected company, and that's what I cannot figure out.
So far I have got as far as using dynamic actions to delete every entry in the table.
Pseudo code for what I am trying to achieve:
SELECT COMPANY_ID FROM COMPANYLIST,
DELETE SELECTED;
Company list being the drop-down box name.

It sounds like you are just struggling with the delete statement?
It should be something like this.
DELETE FROM company
WHERE company_id = (SELECT company_id
FROM companylist
WHERE upper(company_name) = upper(:P1_COMPANY_NAME) );
Replacing company with whatever your company table is called, and :P1_COMPANY_NAME with whatever your select list item is.

Related

Unable to do update table from Apex 5 button Error mentions Cannot Insert NULL

Hi People of the Palace
I am not having luck here and tried a lot of things and seems as if I am not able to get the value from the field which needs to update.
There are 2 fields within Apex 5 which I want to update if something if the value is changed from default. :QUANTITY which is a text field inside of a Tabular form and :DISC which is also a text field in the same row.
There can be single or multiple rows to that needs to be updated and this is usually where you set the option "updated rows and columns only"
The table SALES_TEMP does has columns ID, NAME, QUANTITY_TO_SELL, DISCOUNT.
The PL/SQL code that is assigned in the process to do this update is as follows.
BEGIN
update SALES_TEMP
set QUANTITY_TO_SELL=:QUANTITY, DISCOUNT=:DISC;
end;
When I try and update the fields, it will return with
Cannot insert NULL into QUANTITY_TO_SELL
and similar with the DISCOUNT field.
Now I know there is nothing wrong with the query because if I do this:
BEGIN
update SALES_TEMP
set QUANTITY_TO_SELL='2', DISCOUNT='5';
end;
It does in fact update the table, but it will then do this update to all rows in the table because I have no where clause.
I have had a look through the different options and cannot seem to find why it does not select the data from the fields. My main issue is, I have an exact same query running doing an insert which works.
Also from Apex's Sql Command line option if I run.
update SALES_TEMP
set QUANTITY_TO_SELL=:QUANTITY, DISCOUNT=:DISC;
I get a popup requesting values for :QUANTITY and :DISC and it then updates the columns so something tells me that this is not getting the values from these text fields.
The SQL command to add to populate the fields are
select ID, NAME, QUANTITY_TO_SELL as QUANTITY, DISCOUNT as DISC from SALES_TEMP;
Obviously each gets assigned as :ID, :NAME :QUANTITY and :DISC in apex.
Seeing as you are using Tabular form I suggest you ensure that the following is set.
On the procedure (in processing), Ensure you have the Tabular form selected.
Ensure the Condition "When button is pressed" is set to use the button you want to assign this process to.
in Oracle update clause should ALWAYS have where clause, because oracle will update all data in the table without the WHERE clause.
The cannot insert null error occurs when you are trying to insert in one of the table attributes NULL, where parameter set to NOT NULL, so in your case try to use NVL function, to avoid this issue, I ques that the NAME atribute should not be null.
try to modify your code like this:
update SALES_TEMP
set QUANTITY_TO_SELL = :QUANTITY,
DISCOUNT = :DISC,
NAME = nvl(:NAME,'empty')
where ID = :ID;
in this case it will update only one column.
The Oracle/PLSQL NVL function lets you substitute a value when a null value is encountered.

Update SQL Server table with one time use values from another table

I have a table of users that has the usual suspects, name, email, etc. As the users complete an activity (queried from another table), I need to award them a gift card code.
update users
set giftcardcode = 'code from other table'
where email in (select email from useractivity where necessary conditions are met)
I have a table of unique gift card codes that are unique, one-time use codes. So I need to update my user table, setting the award code field equal to a distinct, unused gift card code from the gift card code table. Then I need to mark the 'used' field in the gift card table to 'Y'.
The goal is to do this with SQL and not any programming. I'm stumped.
I think there is a Many To Many relationship between User table and Activity table.
So, you can use a trigger to execute a query when update.
Each time a row will be updated in the Activity table, the trigger will do something.
It will UPDATE the User table by adding a new gift code.
I think you can add an attribute in your GiftCode table to easily check if the code as already been used. An you can get an unused code like that :
// Retrieve an unused code based on a BIT attribute.
SELECT TOP 1 [Code] FROM [GiftCode] WHERE IS_UNUSED = 1;
Don't forget to update this Gift code after using it.
You can use a SELECT statement including a sub SELECT statement to get a code too :
// Retrieve an unused code based on User table used codes.
SELECT TOP 1 [Code] FROM [GiftCode] WHERE [Code] NOT IN (SELECT [Code] FROM [User]);
It works well if you don't have too much users.
Otherwise , the first statement will be more efficient.
Don't forget to update the User table.
Now you can easily use one of these previous statement in a UPDATE statement.
It will be something like that :
UPDATE [User] SET [Code] = (
SELECT TOP 1 [Code] FROM [GiftCode] WHERE [Code] NOT IN (
SELECT [Code] FROM [User]))
WHERE USER_ID = // ...;
You can perform this in a trigger.
You can use a stored procedure, it's more efficient and will wrap all the SQL code in a compiled function. Then you can call it in your trigger.
You can execute a stored procedure in a job (see SQL Server Agent jobs) too.
create a Trigger on your table for update and do what you want inside it using inserted and deleted

SQL.Working with views

I have a table 'Goods' with different information about goods (name, price, etc). I need to create a view at the same scheme as table 'Goods' has. But the view must be empty. And when user adds new good to the view it is saved in table 'Goods', but the view remains empty when user opens it next time. So main idea is not to show existing data to the user which has access to the view.
Assuming your on a database system that supports a concept like SQL Server's CHECK OPTION, and you're allowed to create a view that doesn't have that option set, you should be fine:
create table T (ID int not null)
go
create view V
as
select * from T where 1=0
go
select * from V
go
insert into V(ID) values (10)
go
select * from V
go
select * from T
The two selects from V return 0 rows. The select from T returns one row:
ID
----
10
CHECK OPTION:
Forces all data modification statements executed against the view to follow the criteria set within select_statement. When a row is modified through a view, the WITH CHECK OPTION makes sure the data remains visible through the view after the modification is committed.
And you want the opposite - you want to allow data modifications performed through the view to create rows which are invisible through the view.
Create table Goods1 with "insert trigger" on it which make insert into Goods and delete from Goods1
As far as I know this isn't possible. The whole point of a view is that it is a view to a table or grouping of tables, ie. it must show the data that matches the view.
http://www.w3schools.com/sql/sql_view.asp
What you could do is create another table called GoodsView and add a trigger to it to INSERT into Goods table and DELETE from GoodsView afterwards.
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=%2Fsqlp%2Frbafysqltrig.htm

Create after insert trigger that updates record in parent table after inserting record into child table

I have two tables
License(licenseId, licenseNumber, lastUsed)
User(userId, userName, dateAdded, licenseId)
After adding a user to a respective license I would like to update the lastUsed field with the most recent date found within the user table using the license.
I am using MS Access
Since you are using Access 2010 you can create an After Insert Data Macro on the [User] table, something like this:

SQL Trigger - Maximo Workorders - Supervisor/Owner Initialization

I am working with an IBM Maximo database that issues workorders automatically. When the workorders are issued (aka Inserted into the database workorder table), I would like to auto-assign a supervisor, owner, and owner group based on a set of criteria. This only needs to happen IF the supervisor, owner, and owner group aren't already assigned. Often times a "parent workorder" has the information, but it needs to be copied into the "child" workorders (as you will see in the criteria below). The criteria for ALL of the triggers is:
WHERE status<>'COMP'
AND historyflag=0
AND istask=0
Here is the criteria for the trigger:
-If the Owner Group and Supervisor have a value, skip the record. (Do nothing)
-If the Owner Group and/or Supervisor is blank or null, and the corresponding PARENT Work
Order field is not Null, copy the Owner Group and/or Supervisor from the
PARENT Work Order record.
-If the Parent Work Order Owner Group and/or Supervisor is blank or null, then
assign the Owner Group and Supervisor per the table values below: (I have removed names for security's sake, but all the columns are correct, i.e. B3 is supposed to have SuperA as the supervisor)
Site / OwnerGroup / Supervisor
ABC / #ABCGroup / #ABCSupervisor
DEF / #DEFGroup / #DEFSupervisor
**NOTE:
SITE is not a table column, it is really the first 3 characters of the workorder.location field. For example, the location could be ABC-1234, meaning it is at site ABC, building 1234 (unfortunately, these are NOT stored in separate columns, they are only present together in the location column). In this SQL query, all buildings at a location are serviced by the same ownergroup/supervisor, so all other queries we currently use are using workorder.location='ABC%'
I've done plenty of selects, updates, and stored procedures, but this is my first trigger and want to make sure I don't royally screw up the database! Any and all help is greatly appreciated!
For those unfamiliar with Maximo, the table is:
dbo.workorder
and the fields are:
location,ownergroup,supervisor
UPDATE1:
Here is some additional information that may be of importance.
Locations:
First off, workorder.location will contain values such as ABC-1234, meaning it is at site ABC, building 1234 (though these are NOT separate values, it's combined). In this SQL query, all buildings at a location are serviced by the same ownergroup/supervisor, so all queries use something similar to workorder.location='ABC%'.
Here is what I would like the logic to look like for the final query:
If the supervisor field is missing, first look to see if it has a parent, and if so, does the parent have a supervisor? If not, assign based on the table above.
If the ownergroup field is missing, first look to see if it has a parent, and if so, does the parent have an ownergroup? If not, assign based on the table above.
This is why I am thinking a case statement maybe the best option. Also, I currently have a list of variables such as "#ASupervisor, #B1Supervisor, #B2Supervisor,...etc" so that I can change them in the future if need be. To save a lot of redundant code, is it possible to do something like:
(in this example, location is ABC-1234, ownergroup SHOULD be #ABCGroup, supervisor should be #ABCSupervisor, where #ABCGroup and #ABCSupervisor are set earlier in the code)
If the supervisor field is missing, first look to see if it has a parent, and if so, does the parent have a supervisor (then copy it's supervisor)? If not, assign supervisor X.
Where X = '#' + '(the first three characters of the location)' + 'Supervisor' (in this example, X=#ABCSupervisor)
Is this possible??
UPDATE 2:
I have spoken with the person who asked for this database change and we have changed some thinking here. First, parent locations and child locations should always be the same (if they're not, that's a WHOLE OTHER issue). All sites (first 3 letters of location) should have the same ownergroup and supervisor, so essentially we can just look to see if a workorder entry has a NULL value in either field, then assign it based on the location. I believe the following code will work (but would like someone to review it before I implement it on the system)
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER dbo.AutoAssign
ON dbo.workorder
AFTER INSERT,UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ABCSupervisor varchar(30)
DECLARE #DEFSupervisor varchar(30)
DECLARE #ABCOwnerGroup varchar(20)
DECLARE #DEFOwnerGroup varchar(20)
/*EDIT VARIABLES IF FUTURE CHANGES*/
--SET Supervisor values HERE;
SET #ABCSupervisor='JOHNDOE'
SET #XYZSupervisor='JANEDOE'
--SET OwnerGroup values HERE:
SET #ABCOwnerGroup='ALPHATEAM'
SET #XYZOwnerGroup='OMEGATEAM'
--UPDATES
UPDATE dbo.workorder
SET ownergroup='#'+SUBSTR(location,1,3)+'OwnerGroup'
WHERE status<>'COMP'
AND historyflag=0
AND istask=0
AND ownergroup IS NULL
AND location IS NOT NULL
UPDATE dbo.workorder
SET supervisor='#'+SUBSTR(location,1,3)+'Supervisor'
WHERE status<>'COMP'
AND historyflag=0
AND istask=0
AND supervisor IS NULL
AND location IS NOT NULL
END
GO
The only issues I see here are that I do not join of some sort on the "inserted" table so that it only affects those entries (and not the entire table every time). If I could get some help on that, it would be greatly appreciated!!
if you have done some update-statements you are on the right way.
put the virtual table INSERTED in your update-statement and join it with a unique-key, e.g. SerialNo: that would be something like that:
create trigger Trig_WorkOrder for insert, update as
BEGIN
update wo
set location = pwo.location, ...
from dbo.workorder as wo, inserted as i, dbo.parentworkorder as pwo
where wo.serialNo = i.SerialNo -- join with the actual table-entry
and wo.pwo_id = pwo.id -- join with the parentworkorder
and i.ownergroup is null -- do it if new value is empty
and (pwo.ownergroup is not null or pwo.ownergroup <> '') -- do it if parentvalue is not empty
and (pwo.Supervisor is not null or pwo.Supervisor <> '') -- do it if parentvalue is not empty
update wo
set location = pwo.location, ...
from dbo.workorder as wo, inserted as i, dbo.standardworkorder as pwo
where wo.serialNo = i.SerialNo
and wo.location = pwo.location
and wo.ownergroup is null
and (pwo.ownergroup is null or pwo.ownergroup = '')
and (pwo.Supervisor is null or pwo.Supervisor = '')
END
I would sugest to store the default values in a separate table, for convenient joining if the parentvalues are empty.
Put two update-statements inside the trigger an code the where-clause to make sure that only one statement executes...
peace and good luck
If you are using Maximo 7.x, automation scripts can do what you want.
For example, we use an automation script that checks to see if the child work order's field is null. If it is, Maximo will take the parent work order value and fill it. In our case, it a custom field called WOPM1.
WorkOrderSet = mbo.getMboSet("PARENT")
if WorkOrderSet.getMbo(0) is not None:
SUPERVISOR = WorkOrderSet.getMbo(0).getString("SUPERVISOR")
Alternatively, if you have a basic lookup to fill in OwnerGroup and Supervisor based on the first three of the location, you can do a if then type logic to fill in data in the child work order when there is a match. v_location is the variable I have defined for a parent work order location:
if v_location == 'ABC':
mbo.setValue("ownergroup","ABCOwnerGroup")
mbo.setValue("supervisor","ABCSupervisor")
For what you are trying to achieve, I'm not sure using a trigger is the best solution in Maximo - using triggers ignores all MBO business logic. Maybe you could consider customizing MBO classes or using Maximo Escalations to do this taks. Using triggers could also get you in trouble when applying Fix Packs or upgrading Maximo so if you choose to go this way, be sure to backup the triggers before any such action.