Get RowID on Progress Insert - sql

I have a table which doesn't have primary key. I needed to add a primary key to the table so I added a column called 'ID'. I am attempting to use the rowid to insert unique ids into this new column. How would I go about getting the rowid when inserting a new record. This is in a Progress database.
INSERT INTO PUB.DETAILS (LASTUPDATED, FORMERVALUE, NEWVALUE, ID)
VALUES ('09/16/2015', 'NEW ITEM', 'ESISTING ITEM', '?')

Progress databases doesn't necessary have a key. At least not in the "SQL way". The keys (as well as the relations) are defined by the business logic (ie how you use the fields.
Since you seem to be working with a database that's in use it might simply be that you don't need a key - there's some kind of logic there already that does the job?
There is a thing called "sequence" in Progress databases that can be used to increase a value - how to access them using odbc or sql I really don't know.
In Progress ABL (4GL) you would say NEXT-VALUE(sequence-name)
Here's some help about SQL and Progress dbs.

Just set your ID column to autoincrement, so you won't need to know the last inserted one.

Related

Insert data into a table with primary key(by skipping the duplicate row)

I have a table with primary Key. When I am running an Insert statement it gives an errror where it finds a duplicate row and stops the insertion. I want to Insert the data into the table by skipping the duplicate row. Can anyone please suggest me how to do this.
Thanks
You haven't tagged which engine you are using so I don't know if this will work for you.
The MERGE statement combines an INSERT/UPDATE/DELETE into a single unit of work.
Your table primary key column has to be of AUTO_INCREMENT so that you don't have to insert that value by yourself, it will take automatically.
And also it will be the best practise for you. Because each time you have to insert the unique value so, on behalf of you the database will take care of it.
If you work with MySQL database then your primary key column has to be of AUTO_INCREMENT type and MySQL will automatically insert new value for PK. If you work with ORACLE, you have to use SEQUENCE as different method which will increment and give you new value for PK.

Insert & Delete from SQL best practice

I have a database with 2 tables: CurrentTickets & ClosedTickets. When a user creates a ticket via web application, a new row is created. When the user closes a ticket, the row from currenttickets is inserted into ClosedTickets and then deleted from CurrentTickets. If a user reopens a ticket, the same thing happens, only in reverse.
The catch is that one of the columns being copied back to CurrentTickets is the PK column (TicketID)that idendity is set to ON.
I know I can set the IDENTITY_INSERT to ON but as I understand it, this is generally frowned upon. I'm assuming that my database is a bit poorly designed. Is there a way for me to accomplish what I need without using IDENTITY_INSERT? How would I keep the TicketID column autoincremented without making it an identity column? I figure I could add another column RowID and make that the PK but I still want the TicketID column to autoincrement if possible but still not be considered an Idendity column.
This just seems like bad design with 2 tables. Why not just have a single tickets table that stores all tickets. Then add a column called IsClosed, which is false by default. Once a ticket is closed you simply update the value to true and you don't have to do any copying to and from other tables.
All of your code around this part of your application will be much simpler and easier to maintain with a single table for tickets.
Simple answer is DO NOT make an Identity column if you want your influence on the next Id generated in that column.
Also I think you have a really poor schema, Rather than having two tables just add another column in your CurrentTickets table, something like Open BIT and set its value to 1 by default and change the value to 0 when client closes the Ticket.
And you can Turn it On/Off as many time as client changes his mind, with having to go through all the trouble of Insert Identity and managing a whole separate table.
Update
Since now you have mentioned its SQL Server 2014, you have access to something called Sequence Object.
You define the object once and then every time you want a sequential number from it you just select next value from it, it is kind of hybrid of an Identity Column and having a simple INT column.
To achieve this in latest versions of SQL Server use OUTPUT clause (definition on MSDN).
OUTPUT clause used with a table variable:
declare #MyTableVar (...)
DELETE FROM dbo.CurrentTickets
OUTPUT DELETED.* INTO #MyTableVar
WHERE <...>;
INSERT INTO ClosedTicket
Select * from #MyTableVar
Second table should have ID column, but without IDENTITY property. It is enforced by the other table.

How do I use ONLY ONE sql query for conditional insert?

I am using swing menu for my Java app. I also have MySQL database. There's a column (named brind) in one of the tables in the database which has to have unique values (other than ID column where values are auto inserted). So through text fields on my JFrame form I will try to insert some values in that table but only if that brind value does not already exist in the table (that is, in the column). I need to have ONLY ONE mysql query for this, call it conditional insert. How do I do this?
Thanks
A query like the following should do what you are asking:
INSERT INTO `thetable`
SELECT 'values', 'to', 'insert'
WHERE NOT EXISTS (
SELECT *
FROM `thetable`
WHERE brind='whatever'
)
Where values,to,insert should be replaced with the values of the fields you are inserting.
However, you would be better served by some of the other suggestions here, e.g.
Check for the value first and don't insert if it exists (do this within one transaction to handle concurrency issues, presuming your transaction isolation is set appropriately),
Attempt the insert and handle the unique constraint violation failure.
Option 2 is a good option, in my opinion.
REPLACE INTO myTable
SET brind = 'someValue'
I think you have a database design problem. If the column brind, has to be unique, the it should probably serve as the primary key.
will try to insert some values in that table but only if that brind
value does not already exist in the table (that is, in the column)
That can be done in database level and application level.
As database level is simplest , safest. Make an index on that column and make it unique (and not identifier!) and the database will not insert if is already exist that value. Here is how to do it.
The application level: you will cache what has the database and you will lock the table, disallowing other apps to modify it. Insert it if you want and unlock table.
I would suggest the first one solution

Avoiding a two step insert in SQL

Let's say I have a table defined as follows:
CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKey varchar(255) NOT NULL,
)
CompoundKey is a string with the primary key P_Id concatenated to the end, like Foo00000001 which comes from "Foo" + 00000001. At the moment, entries insertions into this table happen in 2 steps.
Insert a dummy record with a place holder string for CompoundKey.
Update the CompoundKey with the column with the generated compound key.
I'm looking for a way to avoid the 2nd update entirely and do it all with one insert statement. Is this possible? I'm using MS SQL Server 2005.
p.s. I agree that this is not the most sensible schema in the world, and this schema will be refactored (and properly normalized) but I'm unable to make changes to the schema for now.
Your could use a computed column; change the schema to read:
CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKeyPrefix varchar(255) NOT NULL,
CompoundKey AS CompoundKeyPrefix + CAST(P_Id AS VARCHAR(10))
)
This way, SQL Server will automagically give you your compound key in a new column, and will automatically maintain it for you. You may also want to look into the PERSIST keyword for computed columns which will cause SQL Server to materialise the value in the data files rather than having to compute it on the fly. You can also add an index against the column should you so wish.
A trigger would easily accomplish this
This is simply not possible.
The "next ID" doesn't exist and thus cannot be read to fulfill the UPDATE until the row is inserted.
Now, if you were sourcing your autonumbers from somwhere else you could, but I don't think that's a good answer to your question.
Even if you want to use triggers, an UPDATE is still executed even if you don't manually execute it.
You can obscure the population of the CompoundKey, but at the end of the day it's still going to be an UPDATE
I think your safest bet is just to make sure the UPDATE is in the same transaction as the INSERT or use a trigger. But, for the academic argument of it, an UPDATE still occurs.
Two things:
1) if you end up using two inserts, you must use transaction! Otherwise other processes may see the database in inconsistent state (i.e. seeing record without CompoundKey).
2) I would refrain from trying to paste the Id to the end of CompoundKey in transaction, trigger etc. It is much cleaner to do it at the output if you need it, e.g. in queries (select concat(CompoundKey, Id) as CompoundKeyId ...). If you need it as a foreign key in other tables, just use the pair (CompoundKey, Id).

SQL: No Identity feature workaround using triggers

I'm a little rusty with my triggers and what not and am trying to figure out this problem for a class:
In a database TEST, tables do not have the option of the IDENTITY feature. In other words, when we insert a row into the table “Users”, we would like the primary key “UserID” to auto-increment. Please suggest a workaround to implement this feature without such a built-in functionality.
(Hint: You may still use functions, stored procedures, sequences, triggers, etc)
Use an Int column for the table Primary Key called ID.
You can then use an instead of Insert Trigger, to populate/calculate the value to be inserted for ID.
The trigger will determine what the maximum existing ID is for the table in question (using select MAX ID from TableA) and then increment it by 1 for each record to be inserted.
If there are no records in the table then the ID value is 1.
You use a sequence, and it's very common with Oracle, which does not (or did not once, it may have changed) have identity columns. Since this is homework I'll let you figure out the rest from here.