I want to insert a record into table "SampleTable" and the INSERT statement has 2 real values and one SELECT statement. I know that I could use a Trigger to solve the problem but I need a solution that allows an INSERT statement similar to the one below (which does not work. It produces a "Syntax Error". Thank you for your help in this matter.
CREATE TABLE "SampleTable" (
"SampleTableID" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
"UniqueIdentifier" nvarchar,
"Name" nvarchar(50),
"City" nvarchar(50)
)
INSERT INTO "SampleTable" (
"UniqueIdentifier",
"Name",
"City"
)
VALUES ((SELECT substr(u,1,8)||'-'||substr(u,9,4)||'-4'||substr(u,13,3)||
'-'||v||substr(u,17,3)||'-'||substr(u,21,12) from (
select lower(hex(randomblob(16))) as u, substr('89ab',random() % 4 + 1, 1) as v),"Russel","Dallas");
Use insert . . . select instead of insert . . . values. I think this is the syntax you are looking for:
INSERT INTO "SampleTable" (UniqueIdentifier, Name, City)
SELECT substr(u, 1, 8)||'-'||substr(u, 9, 4)||'-4'||substr(u, 13, 3)||'-'||v||substr(u, 17, 3)||''||substr(u, 21, 12), 'Russel', 'Dallas'
from (select lower(hex(randomblob(16))) as u, substr('89ab',random() % 4 + 1, 1) as v
) toinsert;
Related
In my PostgreSQL database I have the following schema:
CREATE TABLE atc_codes (
id bigint NOT NULL,
name character varying,
atc_code character varying
);
INSERT INTO atc_codes (id, name, atc_code) VALUES (1, 'granisetron', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (2, '', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (3, '', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (4, 'metoclopramide', 'A03FA01');
INSERT INTO atc_codes (id, name, atc_code) VALUES (5, '', 'A03FA01');
INSERT INTO atc_codes (id, name, atc_code) VALUES (6, '', 'A03FA01');
SELECT * FROM atc_codes;
id
name
atc_code
1
granisetron
A04AA02
2
A04AA02
3
A04AA02
4
metoclopramide
A03FA01
5
A03FA01
6
A03FA01
View on DB Fiddle
Now I want to do the following things:
Update all records with act_code equal to A04AA02 to have granisetron value in the name column.
Update all records with act_code equal to A03FA01 to have metoclopramide value in the name column.
In the real database there will be much more scenarios like that so using something like CASE statement is impossible in that case.
Can I do that in one query instead of two?
I found the solution with using view:
WITH act_codes_name AS (
SELECT
name,
atc_code
FROM
atc_codes
WHERE
name IS NOT NULL
)
UPDATE
atc_codes
SET
name = act_codes_name.name
FROM act_codes_name
WHERE act_codes_name.atc_code = atc_codes.atc_code;
Yes you could use a CASE WHEN (standard SQL "switch case") in the SET clause:
UPDATE atc_codes
SET name = CASE
WHEN atc_code = 'A04AA02' THEN 'granisetron'
WHEN atc_code = 'A03FA01' THEN 'metoclopramide'
ELSE name
END
WHERE atc_code IN('A04AA02', 'A03FA01');
To avoid mistakes, I added a ELSE (equivalent to a default case) and a WHERE clause to prevent updating rows that don't match. Both do the same thing and I think you could just use one or the other.
Consider this table:
CREATE TABLE t (i int, j int, ...);
I want to insert data into a table from a set of SELECT statements. The simplified version of my query is:
INSERT INTO t VALUES ((SELECT 1), (SELECT 2), ...);
The real query can be much more complex, and the individual subqueries independent. Unfortunately, this standard SQL statement (which works on SQL Server) doesn't work on SQL Data Warehouse. The following error is raised:
Failed to execute query. Error: Insert values statement can contain only constant literal values or variable references.
Is there a way to work around this?
It appears that there are a few limitations on the INSERT .. VALUES statement of SQL Data Warehouse, but none on INSERT .. SELECT. The requested query can be rewritten to:
INSERT INTO t SELECT (SELECT 1), (SELECT 2);
This workaround is also useful when inserting multiple rows:
-- Doesn't work:
INSERT INTO t VALUES ((SELECT 1), 2), ((SELECT 2), 3), ...;
-- Works:
INSERT INTO t SELECT (SELECT 1), 2 UNION ALL SELECT (SELECT 2), 3;
You can also just run a CREATE TABLE AS SELECT (CTAS) statement. This gives you the full syntax support in the SELECT statement and control of the table shape (distribution type, index type) in the statement. A CTAS statement is fully parallalized.
Strange syntax, but it works. Here is a more complex example:
CREATE TABLE [MDM].[Fact_Management_Curve]
(
[Scenario_ID] INT NOT NULL,
[FundingYYYYMM] CHAR(6) NOT NULL,
[CollectionYYYYMM] CHAR(6) NOT NULL,
[CorpID] INT NOT NULL,
[Multipler] FLOAT NOT NULL
)
GO
INSERT INTO [MDM].[Fact_Management_Curve]
SELECT (SELECT 1), 201701, 201701, 21, 0.010170154301011 UNION ALL
SELECT (SELECT 1), 201701, 201702, 21, 0.010170278901234 UNION ALL
SELECT (SELECT 1), 201701, 201703, 21, 0.010170375659900 UNION ALL
SELECT (SELECT 1), 201701, 201704, 21, 0.010170482998344
GO
SELECT * FROM [MDM].[Fact_Management_Curve]
ORDER BY 1,2,3,4;
Scenario_ID FundingYYYYMM CollectionYYYYMM CorpID Multipler
1 201701 201701 21 0.010170154301011
1 201701 201702 21 0.010170278901234
1 201701 201703 21 0.0101703756599
1 201701 201704 21 0.010170482998344
For your information...
INSERT INTO table_name VALUES Syntax only accepts constant literal values or variable references. Anything like Expression is invalid.
For Example INSERT INTO table_name VALUES (A,B,A+B)
But
DECLARE #C INT = A+B
INSERT INTO table_name VALUES (A,B,C) is valid one.
Here A+B is like any kind of expressions so it throw the error like "only accepts constant literal values or variable references"
Consider this table:
CREATE TABLE t (i int, j int, ...);
I want to insert data into a table from a set of SELECT statements. The simplified version of my query is:
INSERT INTO t VALUES ((SELECT 1), (SELECT 2), ...);
The real query can be much more complex, and the individual subqueries independent. Unfortunately, this standard SQL statement (which works on SQL Server) doesn't work on SQL Data Warehouse. The following error is raised:
Failed to execute query. Error: Insert values statement can contain only constant literal values or variable references.
Is there a way to work around this?
It appears that there are a few limitations on the INSERT .. VALUES statement of SQL Data Warehouse, but none on INSERT .. SELECT. The requested query can be rewritten to:
INSERT INTO t SELECT (SELECT 1), (SELECT 2);
This workaround is also useful when inserting multiple rows:
-- Doesn't work:
INSERT INTO t VALUES ((SELECT 1), 2), ((SELECT 2), 3), ...;
-- Works:
INSERT INTO t SELECT (SELECT 1), 2 UNION ALL SELECT (SELECT 2), 3;
You can also just run a CREATE TABLE AS SELECT (CTAS) statement. This gives you the full syntax support in the SELECT statement and control of the table shape (distribution type, index type) in the statement. A CTAS statement is fully parallalized.
Strange syntax, but it works. Here is a more complex example:
CREATE TABLE [MDM].[Fact_Management_Curve]
(
[Scenario_ID] INT NOT NULL,
[FundingYYYYMM] CHAR(6) NOT NULL,
[CollectionYYYYMM] CHAR(6) NOT NULL,
[CorpID] INT NOT NULL,
[Multipler] FLOAT NOT NULL
)
GO
INSERT INTO [MDM].[Fact_Management_Curve]
SELECT (SELECT 1), 201701, 201701, 21, 0.010170154301011 UNION ALL
SELECT (SELECT 1), 201701, 201702, 21, 0.010170278901234 UNION ALL
SELECT (SELECT 1), 201701, 201703, 21, 0.010170375659900 UNION ALL
SELECT (SELECT 1), 201701, 201704, 21, 0.010170482998344
GO
SELECT * FROM [MDM].[Fact_Management_Curve]
ORDER BY 1,2,3,4;
Scenario_ID FundingYYYYMM CollectionYYYYMM CorpID Multipler
1 201701 201701 21 0.010170154301011
1 201701 201702 21 0.010170278901234
1 201701 201703 21 0.0101703756599
1 201701 201704 21 0.010170482998344
For your information...
INSERT INTO table_name VALUES Syntax only accepts constant literal values or variable references. Anything like Expression is invalid.
For Example INSERT INTO table_name VALUES (A,B,A+B)
But
DECLARE #C INT = A+B
INSERT INTO table_name VALUES (A,B,C) is valid one.
Here A+B is like any kind of expressions so it throw the error like "only accepts constant literal values or variable references"
Imagine I have something like the following
SELECT 0 AS 'Key','No' AS 'Value'
UNION
SELECT 1 AS 'Key','YES' AS 'Value'
UNION
SELECT 2 AS 'Key','Maybe' AS 'Value'
....
....
How can I make above statement more readable so I can accommodate more constant key/value pair in above list in a single select statement? I don't want to create table variable or create a complex sql statement. Just a single select statement returning bunch of constant key/pair values.
You can use VALUES:
SELECT *
FROM (VALUES
(0, 'No'),
(1, 'Yes'),
(2, 'Maybe')
) t([Key], Value)
Table Value Constructor
Using a table value constructor.
VALUES ((0,'NO'),(1,'YES'),(2,'MAYBE'))
Understand you don't want to create a table variable
I use the accepted answer a lot +1
Just pointing out a table variable lets you declare type and primary key
declare #tbl table ([key] tinyint primary key, [value] varchar(12));
insert into #tbl values (1, 'one')
, (2, 'two')
, (3, 'three');
select * from #tbl order by [key];
I'm trying to insert some data to a table contains two things : "a string" and "maximum number in Order column + 1".
This is my query:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (Max([Order]) + 1)
FROM MyTable
What is going wrong with my query?
I'm using Microsoft SQL Server 2005 SP3.
You can test this query like this:
I don't receive error:
create table #MyTable
(
[Text] varchar(40),
[Order] int NOT NULL
)
INSERT INTO #MyTable([Text],[Order])
SELECT 'MyText' [Text], isnull(max([order]) + 1, 0) [Order]
FROM #MyTable
drop table #MyTable
Original:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
or
INSERT INTO MyTable ([Text],[Order])
SELECT top 1 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
limit is not valid in SQL Server as far as I know.
Cannot insert the value NULL into column 'Order', table 'master.dbo.MyTable'; column does not allow nulls. INSERT fails. The statement has been terminated.
This means that the Order column isn't allowed to be null, and that the Max([Order]) + 1 part of your column returns NULL.
This is because your table is empty, as you already noticed by yourself.
You can work around this by replacing NULL by a real number in the query, using ISNULL():
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (isnull(Max([Order]),0) + 1)
FROM MyTable
Unless he has a column named OrderBy
then he would have to add / assign all values within that Insert especially if the column does not allow for nulls
sounds like fully qualifying the Insert with the dbo.MyTable.Field may make more sense.
also why are you naming fields with SQL Key words...???
INSERT INTO MyTable ([Text],[Order] Values('MyTextTest',1)
try a test insert first..