I'm coming from a Teradata environment where
create table mytable
(
first_column varchar(50),
second_column varchar(50),
third_column varchar(50)
)
insert into mytable values (first_column = 'one', second_column = 'first')
insert into mytable values (first_column = 'two', third_column = 'second')
is possible. This does not seem to be possible in HANA even with default specified
create column table mytable
(
"FIRST_COLUMN" varchar(50) default null,
"SECOND_COLUMN" varchar(50) default null,
"THIRD_COLUMN" varchar(50) default null
)
I could create a row with a unique ID specifying NULLs for all the fields and then UPDATE the columns I want using the ID which seems time consuming and awkward or is there a better way?
Use the standard syntax:
insert into mytable (first_column, second_column)
values ('one', 'first');
This should work both in Hana and Teradata -- and any other database.
Related
I have created table like below:
create table EmployeeDetails
(
id int,
name varchar(50),
designation varchar(50),
ReportingTo int
)
And inserted rows like this:
insert into EmployeeDetails values(1, 'A', 'Developer', 3)
insert into EmployeeDetails values(5, 'E', 'CEO', 5)
insert into EmployeeDetails values(2, 'B', 'Developer', 3)
insert into EmployeeDetails values(3, 'C', 'Manager', 4)
insert into EmployeeDetails values(4, 'D', 'S.Manager', 5)
My question is: how can I identify the last inserted row in the table?
Used queries:
select IDENT_CURRENT('EmployeeDetails')
Select SCOPE_IDENTITY()
But I still didn't find the answer.
Replies are always welcome
You have a fundamental misunderstanding of tables in relational databases. They represent unordered sets. So, there is no "last row" in a table. The information on the ordering of rows has to be included when you create the table and/or load data into it.
In SQL Server, the simplest method is an identity column. That is why many tables are defined as:
create table EmployeeDetails (
id int identity primary key,
name varchar(50),
designation varchar(50),
ReportingTo int
);
You can also add default insertion time columns:
create table EmployeeDetails (
id int identity primary key,
name varchar(50),
designation varchar(50),
ReportingTo int,
CreatedAt datetime default gettime()
);
However, you can have multiple rows with the same datetime value.
You also can use rowversion like below,if you add a column
CREATE TABLE MyTest (myKey int
,myValue int, RV rowversion);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);
GO
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);
select * from mytest order by rv desc
Note:
This always give the last row inserted/Updated
References:
rowversion
Add fields of type datetime with name CreateDate and UpdateDate in your table, when you insert record in your table set their value for getdate()
After that you can run queries:
Select top 10 * from YourTable Order By CreateDate DESC
Or for last updated
Select top 10 * from YourTable Order By UpdateDate DESC
Please find my answer as below. Hope this may help you.
Add one more column to store record creation date/time as below.
create table EmployeeDetails
(
id int,
name varchar(50),
designation varchar(50),
ReportingTo int,
CreatedOn datetime
)
After table creation and inserting records write/execute query (here inner query is used) as below
select
*
from EmployeeDetails
where CreatedOn = (select max(CreatedOn) from EmployeeDetails )
I want to insert (user_id) value from a select statement like below without identity column. Currently this query doesn't follow the sequence number in order. Kindly advise.
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=195728e48cc8a5a0047fec8837e9f217
This is answering the original version of the question.
If you are asking can you have identical SQL statements to use a sequence in SQL Server and in Oracle then, no, you cannot.
In Oracle, the syntax is:
INSERT INTO b_user ( user_id /*, ... */ )
VALUES ( b_user__user_id__seq.NEXT_VAL /*, ... */ );
In SQL Server, the syntax is:
INSERT INTO b_user ( user_id /*, ... */ )
VALUES ( NEXT VALUE FOR b_user__user_id__seq /*, ... */ );
In Oracle, you could wrap the call to the sequence in a function:
CREATE FUNCTION get_next_b_user_id RETURN INT
IS
BEGIN
RETURN b_user__user_id__seq.NEXTVAL;
END;
/
Then you could use:
INSERT INTO b_user ( user_id /*, ... */ )
VALUES ( get_next_b_user__id__seq() /*, ... */ );
However, in SQL server you cannot use a sequence in user-defined functions so that approach in Oracle cannot be replicated.
So, in short, you are going to have to use different SQL statements for the different databases if you are using a sequence.
If you want to use an IDENTITY column then you can get the same syntax in both.
In Oracle:
CREATE TABLE b_user (
user_id INT
GENERATED ALWAYS AS IDENTITY,
user_name VARCHAR(250),
user_email VARCHAR(250),
user_address VARCHAR(250),
user_city VARCHAR(50),
user_state VARCHAR(5),
user_country VARCHAR(5),
user_zip VARCHAR(10)
);
and in SQL Server:
CREATE TABLE b_user (
user_id INT IDENTITY(1,1),
user_name VARCHAR(250),
user_email VARCHAR(250),
user_address VARCHAR(250),
user_city VARCHAR(50),
user_state VARCHAR(5),
user_country VARCHAR(5),
user_zip VARCHAR(10)
)
Then, in both databases, you can use the statement:
insert into b_user (
user_name,
user_email,
user_address,
user_city,
user_state,
user_country,
user_zip
) values (
'Alice',
'alice#example.com',
'A house',
'A city',
'STATE',
'ABC',
'ZZ0123'
);
Oracle db<>fiddle and SQL Server db<>fiddle
one option is, if you know know that the column user_id has some values already inserted then when you create a sequence which you are going to use for that column
--example you start with 3 if you know 2 is the maximum value for that column.
CREATE SEQUENCE b_user__user_id__seq start with 3 ;
It is better to have a primary key or unique constraint in that column.
I wanted to create a SQL query which is working like INSERT IF NOT EXISTS ELSE UPDATE
I found that Derby is capable of MERGE and i tried to use it to solve my issue.
MERGE INTO test_table a
USING test_table b
ON a.city = 'foo'
WHEN NOT MATCHED THEN INSERT values ( 'foo', '2012-11-11', 'UK')
WHEN MATCHED AND a.modification_date > '1111-11-11' THEN
UPDATE SET a.modification_date = '2012-11-11',
a.city = 'foo1',
a.country = 'US'
The above statement is giving me the following error:
Error code 30000, SQL state 23505: The statement was aborted because it
would have caused a duplicate key value in a unique or primary key
constraint or unique index identified by 'SQL150129144920080' defined on 'test_table'
How ever i can run the following statement:
INSERT INTO test_table values ( 'foo', '2012-11-11', 'UK');
Which is proving that the above city does not exists in the table yet.
My table is contains the following structure:
CREATE TABLE test_table(
city VARCHAR(100) NOT NULL PRIMARY KEY,
modification_date DATE NOT NULL,
country VARCHAR(2) NOT NULL);
Any help or advice is greatly appreciated.
You have missed the following sentence from here
"The unqualified source table name (or its correlation name) may not be the same as the unqualified target table name (or its correlation name)."
that means you cannot use one table as source and target at the same time !
just one example:
we have two schemas: schema1 and schema2
and two tables: schema1.table1 and schema2.table1
--i have to write all details:
create schema schema1;
create table schema1.table1 (
name varchar(255) not null,
id int not null primary key
);
create schema schema2;
create table schema2.table1 (
name varchar(255) not null,
id int not null primary key
);
--suppose we have inserted some entries into schema2.table1
insert into schema2.table1 values
('foo', 1), ('bar', 2);
--and we want just to copy values from schema2.table1 into schema1.table1
--apply MERGE INTO ... INSERT ...
merge into schema1.table1 as tableTarget
using schema2.table1 as tableSrc
on tableTarget.id= tableSrc.id
when matched then
update set tableTarget.name=tableSrc.name
when not matched then
insert(name, id) values (tableSrc.name, tableSrc.id);
--that has to work
You are not joining table a to table b so the query is likely trying to do an insert for every row in table B, assuming table B contains a city field try
MERGE INTO test_table as a
USING test_table b
ON a.city = b.city and a.city = 'foo'
WHEN NOT MATCHED THEN INSERT values ( 'foo', '2012-11-11', 'UK')
WHEN MATCHED AND a.modification_date > '1111-11-11' THEN
UPDATE SET a.modification_date = '2012-11-11',
a.city = 'foo1',
a.country = 'US';
CREATE TABLE Kitaplar
(
Id INT NOT NULL,
Isim NVARCHAR(50) NOT NULL,
Yazar NVARCHAR(50) NOT NULL,
Resim IMAGE,
Alinis_Tarihi DATE,
Verilis_Tarihi DATE,
PRIMARY KEY (Id)
)
I have this table and I want to create an instance.
insert into Kitaplar values
(003, 'Forty Thorns','Judy Lighy Ayyildiz',null,2012-01-01,2012-02-01)
it doesn't accept these date types.
How should I insert that? And how can I add an image?
I'm using SQL Server 2008 Express.
You need to enclose the dates in quotes as follows:
Insert into Kitaplar values (003, 'Forty Thorns','Judy Lighy Ayyildiz',null,'2012-01-01','2012-02-01')
As far as adding the image, something like this would work (there are other ways to do this too):
Update myTable
Set Image = (SELECT *
FROM OPENROWSET(BULK N'C:\MyImage.jpg', SINGLE_BLOB) test)
Where MyColumn = TargetValue
Is it possible to create a Database which has 1 column (but not the column of primary key) to be auto-increment? So that when I insert value to the database, i don't need to fill in the value myself, and DB will fill in that value for that column for me (and increment every time I do a new insert)?
Thank you.
Yes, of course it is possible. Just make this column a unique key (not a primary key) and it has to be declared with a special attribute: "IDENTITY" for SQL Server, and
"AUTO_INCREMENT" for MySQL (see the example below) . And another column can be a primary key.
On MySQL database the table could be declared like this:
CREATE TABLE `mytable` (
`Name` VARCHAR(50) NOT NULL,
`My_autoincrement_column` INTEGER(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`Name`),
UNIQUE KEY `My_autoincrement_column` (`My_autoincrement_column`)
);
Yes, you can do this. Here is a sample for SQL Server using IDENTITY:
CREATE TABLE MyTable (
PrimaryKey varchar(10) PRIMARY KEY,
IdentityColumn int IDENTITY(1,1) NOT NULL,
DefaultColumn CHAR(1) NOT NULL DEFAULT ('N')
)
INSERT INTO MyTable (PrimaryKey) VALUES ('A')
INSERT INTO MyTable (PrimaryKey) VALUES ('B')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('C', 'Y')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('D', 'Y')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('E', DEFAULT)
--INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('F', NULL) -- ERROR
--> Cannot insert the value NULL into column 'DefaultColumn', table 'tempdb.dbo.MyTable'; column does not allow nulls. INSERT fails.
SELECT * FROM MyTable
Here is an example using SQL Server using functions to roll-your-own incrementing column. This is by means not fault tolerant or the way I would do it. (I'd use the identity feature.) However, it is good to know that you can use functions to return default values.
DROP TABLE MyTable
GO
DROP FUNCTION get_default_for_mytable
GO
CREATE FUNCTION get_default_for_mytable
()
RETURNS INT
AS
BEGIN
-- Declare the return variable here
DECLARE #ResultVar int
-- Add the T-SQL statements to compute the return value here
SET #ResultVar = COALESCE((SELECT MAX(HomeBrewedIdentityColumn) FROM MyTable),0) + 1
-- Return the result of the function
RETURN #ResultVar
END
GO
CREATE TABLE MyTable (
PrimaryKey varchar(10) PRIMARY KEY,
IdentityColumn int IDENTITY(1,1) NOT NULL,
DefaultColumn CHAR(1) NOT NULL DEFAULT ('N'),
HomeBrewedIdentityColumn int NOT NULL DEFAULT(dbo.get_default_for_mytable())
)
GO
INSERT INTO MyTable (PrimaryKey) VALUES ('A')
INSERT INTO MyTable (PrimaryKey) VALUES ('B')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('C', 'Y')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('D', 'Y')
INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('E', DEFAULT)
--INSERT INTO MyTable (PrimaryKey, DefaultColumn) VALUES ('F', NULL) -- ERRROR
--> Cannot insert the value NULL into column 'DefaultColumn', table 'tempdb.dbo.MyTable'; column does not allow nulls. INSERT fails.
SELECT * FROM MyTable
Results
PrimaryKey IdentityColumn DefaultColumn HomeBrewedIdentityColumn
---------- -------------- ------------- ------------------------
A 1 N 1
B 2 N 2
C 3 Y 3
D 4 Y 4
E 5 N 5
I think you can have only 1 identity autoincrement column per table, this columns doesn't have to be the primary key but it would mean you have to insert the primary key yourself.
If you already have a primary key which is auto increment then I would try and use this if possible.
If you are trying to get an row ID to range on for querying then I would look at creating a view which has the row ID in it (not SQL 2000 or below).
Could you add in what your primary key is and what you intend to use the auto increment column for and it might help come up with a solution
On sql server this is called an identity column
Oracle and DB2 have sequence but I think you are looking for identity and all major dbms (mysql, sql server, db2, oracle) support it.