Insert issue Msg 213, Level 16, State 1, Line 2 - sql-server-2012

General newbie SQL question probs...
Why doesn't this work - or, what does this mean?
INSERT INTO test_db.dbo.Customers2
SELECT FirstName
FROM jas_test_db.dbo.Customers
WHERE (Customers.FirstName = Firstname)
I get:
Msg 213, Level 16, State 1, Line 2
Column name or number of supplied values does not match table definition.

You should supply column name for Customers2:
INSERT INTO test_db.dbo.Customers2(**Firstname**)
SELECT FirstName
FROM jas_test_db.dbo.Customers
WHERE (Customers.FirstName = Firstname)

I would recommend to always explicitly specify which columns you want to insert into:
INSERT INTO test_db.dbo.Customers2(FirstName) -- <-- specify the columns you want to insert into!
SELECT FirstName
FROM jas_test_db.dbo.Customers
WHERE (Customers.FirstName = Firstname)
If you don't do this, you have to provide values for all columns, in the exact order in which they are defined in the table

Related

How to Use the OUTPUT of an Insert Query for another insert query

I'm trying to insert 2 records into 2 tables by using a subquery, but it gives me a syntax error.
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'INSERT'.
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near ')'.
The query that I'm trying to execute is
INSERT INTO [Files] ([FileTransformationId],[FileTypeEnumId])
VALUES
(
(INSERT INTO [FileTransformations] OUTPUT INSERTED.FileTransformationId DEFAULT VALUES),
2
)
Is this possible?
You need to store the output in a variable first. So, I think you want something like this:
DECLARE #variable TABLE (value INT)--change type depending on your need
INSERT INTO [FileTransformations]
OUTPUT INSERTED.FileTransformationId INTO #variable(value)
VALUES(.....)
INSERT INTO [Files] ([FileTransformationId],[FileTypeEnumId])
SELECT value, 2 FROM #variable
See How do I use an INSERT statement's OUTPUT clause to get the identity value? for more info on using output variables and Insert into table from table variable? for then inserting from that table variable.
Another option, if you just want the id of the last inserted record is to use scope_identity(). So you could write the above as:
INSERT INTO [FileTransformations]
VALUES(.....)
INSERT INTO [Files] ([FileTransformationId],[FileTypeEnumId])
VALUES scope_identity(), 2

SQL Insert invalid column name non-numeric values only

I am writing a very basic insert statement. I noticed that the error message "Invalid column name" appears if the VALUE is a character besides a number.
The data type is VARCHAR(50) on all three columns.
Database: MS SQL 2012
Query:
INSERT INTO [test-db].[dbo].[Computer]
([id]
,[name]
,[office])
VALUES
(123
,john
,main)
GO
ERROR:
Msg 207, Level 16, State 1, Line 1
Invalid column name 'john'.
Msg 207, Level 16, State 1, Line 1
Invalid column name 'main'.
Change your query to this
INSERT INTO [test-db].[dbo].[Computer]
([id]
,[name]
,[office])
VALUES
(123
,'john'
,'main')
GO
The varchar needs quotes around it to work.

SQL rollup two columns error

i am having error in SQL saying:
Msg 213, Level 16, State 1, Line 7
Column name or number of supplied values does not match table definition.
Code:
CREATE TABLE temp
(
kolA varchar(255),
kolB varchar(255)
);
INSERT temp VALUES
('A','B'),
('B','B'),
('B','B'),
('A','B'),
(null,'B'),
('B','B');
select kolA,kolB,ilośc = COUNT(*) from temp
GROUP BY rollup(kolA,kolB);
DROP TABLE temp
i do not know why this error occurs, can someone tell me?
This works fine against 2008 in a fiddle.
http://sqlfiddle.com/#!3/61dc9d/1

Inserting last two digits from column into new column

So I'm supposed to take the last two digits from the phone number, and insert it into a new column in the same table.
I'm currently getting this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'Pass_id', table 'lunches.dbo.passenger'; column does not allow nulls. INSERT fails.
The statement has been terminated.
This is the query I'm using to get this error:
INSERT INTO dbo.passenger (age)
SELECT
RIGHT(phone, 2)
FROM dbo.passenger
UPDATE dbo.passenger
SET age = Cast(Right(phone, 2) As tinyint)
WHERE phone IS NOT NULL
AND Right(phone, 2) NOT LIKE '%[^0-9]%'

OUPUT for insert from table variable gives: "The multi-part identifier "k.CustomerName" could not be bound."

I have seen many people here on stack overflow with this error message and all get it in another situation. I could not find my own situation among the already existing questions. So I hope someone can help me with this. I use SQL server 9 with SQL management studio 10.
--import the customers.
CREATE TABLE #AllCustomers(CustomerName NVARCHAR(100), CustomerNr NVARCHAR(16));
BULK INSERT #AllCustomers
FROM 'C:\allcustomers.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
);
DECLARE #DefinitionId int;
--get the id of the definition for which I have to set values.
SELECT #DefinitionId = pkDefinitionId
FROM dbo.Definitions
WHERE Name = 'DEFINITION-OF-MY-ITEM';
DECLARE #TempA TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16));
--reduce the set of all customers to only the customer for whom I have to insert.
WITH MyView AS
(SELECT kciv.CustomerNr
FROM dbo.CustomerItems kciv
INNER JOIN dbo.DefinitionToItem civ ON civ.pkDefinitionToItemId = kciv.pkCustomerItemId
WHERE civ.fkDefinitionId = #DefinitionId)
INSERT INTO #TempA
SELECT k.CustomerName , k.CustomerNr
FROM #AllCustomers k
WHERE k.CustomerNr NOT IN (SELECT CustomerNr FROM MyView);
--used to store the generated primairy keys I need for creating relations.
DECLARE #ItemIds TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16), pkItemId int);
DECLARE #DefinitionToItemIds TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16), pkDefinitionToItemId int);
--insert the default values.
INSERT INTO dbo.Items
OUTPUT k.CustomerName, k.CustomerNr, inserted.pkItemId
INTO #ItemIds (CustomerName, CustomerNr, pkGenericValueId)
SELECT 2, 1, null, null, 1, null
FROM #TempA k;
--couple the values to the definition.
INSERT INTO dbo.DefinitionToItem
OUTPUT gvd.CustomerName, gvd.CustomerNr, inserted.pkDefinitionToItemId
INTO #DefinitionToItemIds
SELECT 1, 0, #DefinitionId, gvd.pkItemId
FROM #ItemIds gvd;
--couple the 'coupling' to the customers.
INSERT INTO dbo.CustomerItems
SELECT civd.pkDefinitionToItemId, civd.CustomerName, civd.CustomerNr
FROM #DefinitionToItemIds civd;
I get four errors when running the query, all on the two output lines near the end of the code sample.
Msg 4104, Level 16, State 1, Line 64 The multi-part identifier "k.CustomerName" could not be bound.
Msg 4104, Level 16, State 1, Line 64
The multi-part identifier "k.CustomerNr" could not be bound.
Msg 4104, Level 16, State 1, Line 69
The multi-part identifier "gvd.CustomerName" could not be bound.
Msg 4104, Level 16, State 1, Line 69
The multi-part identifier "gvd.CustomerNr" could not be bound.
I have checked for typos but couldn't find any (I might have introduced some here though while changing some of the names to remove the context). I can't find out why this is going wrong. I've looked at MSDN, but I can't find anything wrong.
Extra info:
The database schema is as follows:
The Items table contains "values" (pkItemId, bunch of other columns)
The Definition table contains "definitions" (pkDefinitionId, Name, bunch of other columns)
The DefinitionToItem table matches the values to definitions (pkDefinitionToItemId, fkDefinitionId, fkItemId)
The CustomerItems table links a customer to a DefinitionToItemId (pkDefinitionToItemId, CustomerName, CustomerNr).
What I need to achieve is to insert default values (i.e. "2, 1, null, null, 1, null" linked to definitino 'DEFINITION-OF-MY-ITEM') into the items database for a given set of customers. Some might already have a value for that definition and then I should skip them (hence the #TempA).
So I insert the value into Items, then insert the coupling between definition and items in DefinitionToItem and lastly couple the customer to the DefinitionToItem by inserting into the DefinitionToItem table.
If there if a better way to achieve this than through what I'm doing, then I'm open to suggestions.
I think the approach you are taking is complicating the scenario.
Firstly, the OUTPUT clause is not going to work the way you need it to work here, because you can only use columns inserted, and you want to use columns from the source table, but ones that does not get inserted. (CustomerName as an example).
There are two ways I suggest you can go about this:
First Approach. Change you query. Use OUTPUT, but output an id field. Then, after your first insert into ITEMS, join your new table with your source table. NOW you will have access to all fields and still a way to identify which records should be inserted.
Second approach. Drop your temp tables. Use a simple insert statement with a WHERE _ NOT IN clause. This takes away the complexity and still achieves the goal of not inserting duplicates, just on a closer level.
Use:
INSERT INTO dbo.Items
OUTPUT INSERTED.CustomerName, INSERTED.CustomerNr, INSERTED.pkItemId
INTO #ItemIds (CustomerName, CustomerNr, pkGenericValueId)
SELECT 2, 1, null, null, 1, null
FROM #TempA k;
INSERT INTO dbo.DefinitionToItem
OUTPUT INSERTED.CustomerName, INSERTED.CustomerNr, INSERTED.pkDefinitionToItemId
INTO #DefinitionToItemIds
SELECT 1, 0, #DefinitionId, gvd.pkItemId
FROM #ItemIds gvd;
You might need to change the column names, because they need to come from the table being inserted into rather than the column they were sourced from.
Your table #AllCustomers does not contain field CustomerName in this query
SELECT k.CustomerName , k.CustomerNr
FROM #AllCustomers k