Code below using sample data.
INSERT INTO ClientSeller VALUES
(1,'John Smith',88,1,'a',1),
(2,'Joe Smith',12,2,'b',2),
(3,'Warren ',15,2,'c',3),
(4,'Karen',69,6,'d',5),
(5,'Bob',45,6,'e',55),
(6,'Owen',65,6,'f',4),
(7,'Steve',25,5,'g',8),
(8,'Peter',24,55,'a',88),
(9,'Zoe',245,8,'b',8),
(10,'Jacky',244,2,'c',8);
and displays :
ORA-00933: SQL command not properly ended
Can any explain why this does not execute?
Based on your example, I created the following table.
Create table ClientSeller (
identity number(2),
name varchar2(50),
employeno number(2),
otherno number(1),
letter char(1),
otherotherno number(1)
)
Then using the code below I can insert two of your sample rows into the table. Oracle has a very clunky syntax for inserting values into a table. You absolutely need the Insert All with separate INTO tablename VALUES xxxxx for each values set and then at the end you MUST add the select 1 from DUAL. See this example for more details.
Also, do not end your statements with the semicolon. In none of the example code provided here will you find such a character.
INSERT ALL
INTO ClientSeller VALUES (1,'John Smith',88,1,'a',1)
INTO ClientSeller VALUES (2,'Joe Smith',12,2,'b',2)
SELECT 1 from DUAL
Related
I am trying to insert into Table Users from Person table.
However, The first_name column in the person table contains apostrophe in the name (Eg- Rus'sell) which is preventing me from successful insertion. How do I fix this?
INSERT INTO USERS VALUES (SELECT FIRST_NAME,.........FROM PERSON);
INSERT INTO USERS VALUES (SELECT FIRST_NAME,.........FROM PERSON);
First of all, your insert statement is syntactically incorrect. It will raise ORA-00936: missing expression. The correct syntax to insert multiple records from source table is:
INSERT INTO table_name SELECT columns_list FROM source_table;
The VALUES keyword is used to insert a single record into table using following syntax:
INSERT INTO table_name(columns_list) VALUES (expressions_list);
If you already have the value stored in another table, then simple INSERT INTO..SELECT FROM should work without any issues. However, if you are trying to INSERT INTO..VALUES having single quotation marks, then the best way is to use Quoting string literal technique The syntax is q'[...]', where the "[" and "]" characters can be any of the following as long as they do not already appear in the string.
!
[ ]
{ }
( )
< >
You don't have to worry about the single-quotation marks within the string.
create table t(name varchar2(100));
insert into t values (q'[Rus'sell]');
insert into t values (q'[There's a ' quote and here's some more ' ' ']');
select * from t;
NAME
-----------------------------------------------
Rus'sell
There's a ' quote and here's some more ' ' '
I don't think your question is showing the complete details, because I can execute the following statements without any problem:
create table person( first_name varchar2(100));
create table users( first_name varchar2(100));
insert into person values ('Rus''sell');
insert into users select first_name from person;
Apologies for the obscurity if any in the question. The query I was working with was a long insert query with multiple joins.
To sum it was a stored proc where I was doing an insert, for which the data is given by long select query with multiple joins. One of the column is the FIRST_NAME column which had some values with Apostrophe in it (Rus'sell, Sa'm).
The Insert statement values were being generated as below which was causing an 'ORA-00917: missing comma' error.
INSERT INTO TABLE_NAME values (314159,0,'Rus'sell','Parks','...........)
I fixed this by Replacing the column in the select from a single quote to two single quotes, before giving it to the insert statement which basically solved the issue.
REPLACE(FIRST_NAME,'''','''''') AS FIRST_NAME
Hope it helps.
I'm new to firebird and I have verious issues. I want to insert various lines into a table selected from another table.
Here's the code:
/*CREATE GENERATOR POS; */
SET GENERATOR POS TO 1;
SET TERM ^;
create trigger BAS_pkassign
for MATERIAL
active before insert position 66
EXECUTE BLOCK
AS
declare posid bigint;
select gen_id(POS, 1)
from RDB$DATABASE
into :posid;
BEGIN
END
SET TERM ; ^
INSERT INTO MATERIAL ( /*ID */ LOCATION, POSID, ARTID, ARTIDCONT, QUANTITY )
SELECT 1000, ':posid', 309, BAS_ART.ID, 1
FROM BAS_ART
WHERE BAS_ART.ARTCATEGORY LIKE '%MyWord%'
The ID should autoincrement from 66 on. The posid should autoincrement from 1 on.
Actually it is not inserting anything.
I'm using Firebird Maestro and have just opened the SQL Script Editor (which doesnt throw any error message on executing the script).
Can anybody help me?
Thanks!
Additional information:
The trigger should autoincrement the column "ID" - but I dont know how exactly I can change it so it works.. The ':posid' throws an error using it :posid but like this theres no error (I guess its interpretated as a string). But how do I use it right?
I dont get errors when I execute it. The table structure is easy. I have 2 tables:
1.
Material (
ID (INTEGER),
Location (INTEGER),
POSID (INTEGER),
ARTID (INTEGER),
ARTIDCONT (INTEGER),
QUANTITY (INTEGER),
OTHERCOLUMN (INTEGER))
and the 2. other table
BAS_ART (ID (INTEGER), ARTCATEGORY (VARCHAR255))
-> I want to insert all entries from the table BAS_ART which contain "MyWord" in the column ARTCATEGORY into the MATERIAL table.
I don't understand why you need the trigger at all.
This problem:
I want to insert all entries from the table BAS_ART which contain "MyWord" into the MATERIAL table
Can be solved with a single insert ... select statement.
insert into material (id, location, posid, artid, quantity)
select next value for seq_mat_id, 1000, next value for seq_pos, id, 1
from bas_art
where artcategory = 'My Word';
This assumes that there is a second sequence (aka "generator") that is named seq_mat_id that provides the new id for the column material.id
For most of my answer I will assume a very simple table:
CREATE TABLE MyTable (
ID BIGINT PRIMARY KEY,
SomeValue VARCHAR(255),
posid INTEGER
)
Auto-increment identifier
Firebird (up to version 2.5) does not have an identity column type (this will be added in Firebird 3), instead you need to use a sequence (aka generator) and a trigger to get this.
Sequence
First you need to create a sequence using CREATE SEQUENCE:
CREATE SEQUENCE seqMyTable
A sequence is atomic which means interleaving transactions/connections will not get duplicate values, it is also outside transaction control, which means that a ROLLBACK will not revert to the previous value. In most uses a sequences should always increase, so the value reset you do at the start of your question is wrong for almost all purposes; for example another connection could reset the sequence as well midway in your execution leaving you with unintended duplicates of POSID.
Trigger
To generate a value for an auto-increment identifier, you need to use a BEFORE INSERT TRIGGER that assigns a generated value to the - in this example - ID column.
CREATE TRIGGER trgMyTableAutoIncrement FOR MyTable
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
NEW.ID = NEXT VALUE FOR seqMyTable;
END
In this example I always assign a generated value, other examples assign a generated value only when the ID is NULL.
Getting the value
To get the generated value you can use the RETURNING-clause of the INSERT-statement:
INSERT INTO MyTable (SomeValue) VALUES ('abc') RETURNING ID
INSERT INTO ... SELECT
Using INSERT INTO ... SELECT you can select rows from one table and insert them into others. The reason it doesn't work for you is because you are trying to assign the string value ':pos' to a column of type INTEGER, and that is not allowed.
Assuming I have another table MyOtherTable with a similar structure as MyTable I can transfer values using:
INSERT INTO MyTable (SomeValue)
SELECT SomeOtherValue
FROM MyOtherTable
Using INSERT INTO ... SELECT it is not possible to obtain the generated values unless only a single row was inserted.
Guesswork with regard to POSID
It is not clear to me what POSID is supposed to be, and what values it should have. It looks like you want to have an increasing value starting at 1 for a single INSERT INTO ... SELECT. In versions of Firebird up to 2.5 that is not possible in this way (in Firebird 3 you would be able to use ROW_NUMBER() for this).
If my guess is right, then you will need to use an EXECUTE BLOCK (or a stored procedure) to assign and increase the value for every row to be inserted.
The execute block would be something like:
EXECUTE BLOCK
AS
DECLARE posid INTEGER = 1;
DECLARE someothervalue VARCHAR(255);
BEGIN
FOR SELECT SomeOtherValue FROM MyOtherTable INTO :someothervalue DO
BEGIN
INSERT INTO MyTable (SomeValue, posid) VALUES (:someothervalue, :posid);
posid = posid + 1;
END
END
Without an ORDER BY with the SELECT the value of posid is essentially meaningless, because there is no guaranteed order.
A SAMPLE table has only one column ID of type int, default null.
In Oracle when I do:
insert into SAMPLE (ID) values ('');
the new record is added with blank value. But in SQL Server 2008, when I run the same insert statement, the new record has the value of 0.
Is there a way to force SQL Server 2008 to default blank string to NULL instead of 0 (for numerical type of columns)?
Assuming that your INSERT statement is part of a stored procedure re-used in many places of your application (or, perhaps, is a batch always constructed by the same part of the client code) and that the inserted value is a number passed as a string argument, you could modify the INSERT like this:
INSERT INTO SAMPLE (ID) VALUES (NULLIF(#argument, ''));
Use NULL instead.
insert into SAMPLE (ID) values (NULL);
How about another idea - define an INSTEAD OF INSERT Trigger.
Despite the fact that you're trying to insert a string, with this the operation is "intercepted", empty string is replaced by NULL, and the insert succeeds.
If you define this trigger on your table, then you can continue to insert empty string as before, with no other changes.
Edit: As Martin Smith points out, this effectively is a comparison to 0 (the equivalent of empty string as an int) meaning you won't be able to store 0 in this table. I leave this answer here in case that's acceptable to your situation - either that or re-do all your queries!
CREATE TRIGGER EmptyStringTrigger
ON [SAMPLE]
INSTEAD OF INSERT
AS
BEGIN
INSERT INTO [SAMPLE](ID)
SELECT CASE
WHEN ID = '' THEN NULL
ELSE ID
END
FROM inserted
END
SQL Fiddle example
You can't insert a 'string' into a int column. Oracle must be just handling that for you.
Just try inserting NULL if that's what you need.
insert into SAMPLE (ID) values (NULL);
One more option
insert into SAMPLE (ID) values (DEFAULT)
I create a table and sequence in order to replace identity in the table I use SQL Server 2012 Express but I get this error while I tried to insert data to the table
Msg 11719, Level 15, State 1, Line 2
NEXT VALUE FOR function is not allowed in check constraints, default objects, computed columns,
views, user-defined functions, user-defined aggregates, user-defined
table types, sub-queries, common table expressions, or derived
tables.
T-SQL code:
insert into Job_Update_Log(log_id, update_reason, jobid)
values((select next value for Job_Log_Update_SEQ),'grammer fixing',39);
This is my table:
create table Job_Update_Log
(
log_id int primary key ,
update_reason nvarchar(100) ,
update_date date default getdate(),
jobid bigint not null,
foreign key(jobid) references jobslist(jobid)
);
and this is my sequence:
CREATE SEQUENCE [dbo].[Job_Log_Update_SEQ]
AS [int]
START WITH 1
INCREMENT BY 1
NO CACHE
GO
Just get rid of the subselect in the VALUES section, like this:
insert into Job_Update_Log(log_id,update_reason,jobid)
values (next value for Job_Log_Update_SEQ,'grammer fixing',39);
Reference: http://msdn.microsoft.com/en-us/library/hh272694%28v=vs.103%29.aspx
Your insert syntax appears to be wrong. You are attempting to use a SELECT statement inside of the VALUES section of your query. If you want to use SELECT then you will use:
insert into Job_Update_Log(log_id,update_reason,jobid)
select next value for Job_Log_Update_SEQ,'grammer fixing',39;
See SQL Fiddle with Demo
I changed the syntax from INSERT INTO VALUES to INSERT INTO ... SELECT. I used this because you are selecting the next value of the sequence.
However, if you want to use the INSERT INTO.. VALUES, you will have to remove the SELECT from the query:
insert into Job_Update_Log(log_id,update_reason,jobid)
values(next value for Job_Log_Update_SEQ,'grammer fixing',39);
See SQL Fiddle with Demo
Both of these will INSERT the record into the table.
Try this one:
–With a table
create sequence idsequence
start with 1 increment by 3
create table Products_ext
(
id int,
Name varchar(50)
);
INSERT dbo.Products_ext (Id, Name)
VALUES (NEXT VALUE FOR dbo.idsequence, ‘ProductItem’);
select * from Products_ext;
/* If you run the above statement two types, you will get the following:-
1 ProductItem
4 ProductItem
*/
drop table Products_ext;
drop sequence idsequence;
------------------------------
I have created table using this command successfully
create table Person(
first_name varchar(25) not null,
last_name varchar(25) not null,
persoin_id number not null,
birth_date date,
country varchar (25),
salary number);
and now I want to insert data into that table
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia');
first row is inserted,but problem is with second line
1 rows inserted.
Error starting at line 10 in command:
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
Error report:
Unknown Command
Please help me to determine what is problem?thanks
If you are on a RDBMS that supports multi-rows inserts in one INSERT:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia') ,
--- comma here ---^
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia') ;
^--- no "values" here
If not (like Oracle), you'll have to issue two insert statements:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia') ;
--- as it was here ---^
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia') ;
or use this approach:
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
select
(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia')
from dual
union all select
(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
from dual
;
You will need to use 2 insert statement instead of one for 2 different sets of data...
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
insert into Person(persoin_id,first_name,last_name,salary,birth_date,country)
values(101,'irakli','oqruashvili',350,to_date('01/03/10','DD/MM/YY'),'georgia')
You have a ; at the end of:
values(100,'dato','datuashvili',350,to_date('01/01/10','DD/MM/YY'),'georgia');
^
change it to , and also loose the values from the next line. You need just one values per insert.