INSERT INTO BORCODEME
( BORCODEME.IslemTarihi, BORCODEME.IslemAciklamasi,BORCODEME.IslemTutari)
VALUES(
(SELECT BORCLAR.BorcTarih,BORCLAR.BorcAciklama,BORCLAR.BorcTutari FROM BORCLAR WHERE BORCLAR.BorcMusteriID=6),
(SELECT ODEMELER.OdemeTarihi,ODEMELER.OdemeAciklama,ODEMELER.OdemeTutar FROM ODEMELER WHERE ODEMELER.OdemeMusteriID=6)
)
My SQL command is this, and I have these errors;
Msg 116, Level 16, State 1, Line 4
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 116, Level 16, State 1, Line 6
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Msg 109, Level 15, State 1, Line 1
There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
Not sure what you're really looking for - are you trying to insert the three columns from the two tables? Then write your INSERT like this:
INSERT INTO BORCODEME(IslemTarihi, IslemAciklamasi, IslemTutari)
SELECT
BORCLAR.BorcTarih, BORCLAR.BorcAciklama, BORCLAR.BorcTutari
FROM
BORCLAR
WHERE
BORCLAR.BorcMusteriID = 6
UNION
SELECT
ODEMELER.OdemeTarihi, ODEMELER.OdemeAciklama, ODEMELER.OdemeTutar
FROM
ODEMELER
WHERE
ODEMELER.OdemeMusteriID = 6
So this will insert the three values from BORCLAR and another row with the three values from ODEMELER.
If that's not what you want, then you need to explain in more detail what you really want instead.....
In general, you can either use this syntax:
INSERT INTO dbo.TargetTable (List-of-Columns)
VALUES (List-of-atomic-values)
or if you cannot provide atomic values (literals or T-SQL variables), then you can use
INSERT INTO dbo.TargetTable (List-of-Columns)
SELECT list-of-columns
FROM dbo.SourceTable
(but you cannot mix - you cannot have VALUES and then use SELECT inside of it)
In both cases, the number of columns in the INSERT statement must match exactly with the number of atomic values provided in VALUES or the number of columns selected by the SELECT statement
Related
I wrote a function (dbo.fFunctionCols) with 2 parameters (1st is tablename, 2nd is search pattern for column names) that returns certain column names from a table and passes them to the query below in which the same table is unpivoted. The query should end up as a view.
SELECT Id, AB, vTime, vItem, vCount
FROM
(SELECT Id, AB, vTime,
dbo.fFunctionCols('tablename', 'abc%def')
FROM dbo.[tablename]) AS piv
UNPIVOT
(vCount FOR vITEM IN
(SELECT dbo.fFunctionCols('tablename', 'abc%def') AS t1
) AS unpiv;
GO
SQL Server always returns:
Msg 156, Level 15, State 1, Line 8
Incorrect syntax near the keyword 'SELECT'.
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near ')'.
The statement:
SELECT dbo.fFunctionCols('tablename', 'abc%def') AS t1
works properly if executed. It delivers the correct list of the relevant column names seperated with commas and enclosed in square brackets.
What´s the error? Why can the function not be used inside the IN operator?
I am trying the following SQL but I get an error:
CREATE TABLE slipstream( visit_timestamp time);
INSERT INTO slipstream values(dateadd(second, uniform(1, 10, random()), current_time()));
Error:
Invalid expression [DATE_ADDSECONDSTOTIME(CAST(UNIFORM(1, 10, RANDOM()) AS NUMBER(2,0)), '12:52:29.050000000')] in VALUES clause
Please advise
Using INSERT - SELECT pattern:
INSERT INTO slipstream (visit_timestamp)
SELECT dateadd(second, uniform(1, 10, random()), current_time());
Output:
The VALUES requires constants and allows for simple casting that the SQL parser can do, thus in the values line you can have '2022-06-21'::date and that will correctly cast to DATE.
SELECT column1, system$typeof(column1) FROM VALUES
('2022-06-21'::date),
('2022-05-21'::date);
gives:
COLUMN1
SYSTEM$TYPEOF(COLUMN1)
2022-06-21
DATE[SB4]
2022-05-21
DATE[SB4]
And thus for this workflow it would have been valid to use:
INSERT INTO slipstream VALUES
('2022-06-21'::timestamp),
('2022-05-21'::timestamp);
number of rows inserted
2
But complex function calls need to be executed SQL, thus as Lukasz mentioned the need for the INSERT/SELECT pattern.
Now you can be clever and put a VALUES on the SELECT to data drive the parameters to those functions (I was hoping to be clever as using the values to uniform, but those need to be constants, so settled for an offset)
CREATE TABLE slipstream( visit_timestamp time);
INSERT INTO slipstream
SELECT dateadd(second, uniform(1, 10, random() ) + column1, current_time() )
FROM VALUES
(0),
(-10),
(-20);
number of rows inserted
3
SELECT * FROM slipstream;
VISIT_TIMESTAMP
16:18:04
16:17:55
16:17:42
When I try this on SQL Server 2014:
INSERT INTO B_G049
SELECT B049_Z001, B049_Z002, ObjectId1, ObjectId7, 43099 AS value
FROM B_G049
WHERE value = 42734;
with decimals columns, I get an error:
Msg 8115, Level 16, State 8, Line 56
Arithmetic overflow error converting int to data type numeric.
I have never noticed such problem with copy rows between the same structure tables (in this case same table is input and output) using
INSERT INTO table1
SELECT (list of columns)
FROM table1
WHERE (condition)
I created a database table:
I run this query
INSERT INTO dbo.Stats (Date_of_Record, Rack_Code, Total_MB, Schools_MB, Percent_Schools, Central_MB, Percent_Central)
VALUES (CAST(GETDATE() AS DATE), '78Q425', 45, 297, 1, 361, 0, 12, 0)
and I get an error
Msg 110, Level 15, State 1, Line 1
There are fewer columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.
However, this works, but why should I NOT insert number with commas?
INSERT INTO dbo.Stats (Date_of_Record, Rack_Code, Total_MB, Schools_MB, Percent_Schools, Central_MB, Percent_Central)
VALUES (CAST(GETDATE() AS DATE), '78Q425', 45297, 1361, 0, 12, 0)
Commas delimit values. By using commas, you are telling SQL Server to expect more columns of data. SQL Server is not white space sensitive, so white space is not used as a delimiter.
I write a insert trigger which work is: when a row inserted into the table then it update a particular field by a 20 char unique number which is generated using time and random number. It working fine when I insert a single row. But problem happens when I insert multiple rows using a single insert statement.
My trigger & insert query and error are below:
Trigger:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER TRIGGER [unique_outmsg_id]
ON [dbo].[tbl_subscription]
FOR INSERT
AS
BEGIN
DECLARE #random_number varchar(6);
DECLARE #time_value varchar(23);
DECLARE #unique_id varchar(20);
SELECT #random_number = convert(varchar,(SELECT CAST(RAND() * 999 AS INT)));
SELECT #time_value = convert(varchar,(select replace(replace(replace(replace(convert(varchar(23), getdate(), 121),'-',''),'.',''),' ',''),':','')));
SELECT #unique_id=(SELECT(#time_value+#random_number));
UPDATE dbo.tbl_subscription SET outmsg_id=#unique_id WHERE outbox_id=(SELECT outbox_id FROM inserted)
END
Output of the trigger: 20110724093323697833
Multiple row insert query:
USE [test_abc]
INSERT INTO [test_abc].[dbo].[tbl_subscription] (inbox_id,inmsg_id,enabled)
SELECT s.inbox_id,s.enabled
FROM [test_def].[dbo].[tbl_subscriberlist] s,[test_def].[dbo].infoservice i
WHERE s.mo_key = 'ABC' AND i.subscribtionKey='ABC'
Functionality of this query:
To collect the information from another table and insert into tbl_subscription multiple rows.
But the error is when I run this query:
Msg 512, Level 16, State 1, Procedure unique_outmsg_id, Line 13
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression. The statement has been terminated.
So, why this error is happen when I am inserting multiple rows into the table?? Any ideas? Please help.
Triggers must be written to handle multiple rows.
The problem is in this update statement:
UPDATE dbo.tbl_subscription
SET outmsg_id=#unique_id
WHERE outbox_id = (SELECT outbox_id FROM inserted)
It expects the subselect (SELECT outbox_id FROM inserted) to return only a single row (which of course it won't when the trigger is fired for a multi-row batch).
You need to rewrite your UPDATE statement as a join to the inserted table
Multirow Considerations for DML Triggers
Implementing DML Triggers
This is returning all rows. You can only select 1 values into a field
WHERE outbox_id = (SELECT outbox_id FROM inserted)
Instead try (I can't test it though)
UPDATE s
SET outmsg_id=#unique_id
dbo.tbl_subscription s
JOIN inserted i
ON s.outbox_id=i.outbox_id
Furthermore this will always return the same number, which i imagine is not indended
SELECT #random_number = convert(varchar,(SELECT CAST(RAND() * 999 AS INT)));
Instead try:
SELECT #random_number = convert(varchar,(CAST(RAND(ABS(CHECKSUM(NEWID())))*999 AS INT) AS INT)));
(I recognize some of Mikael Eirikson's code in your statement)