SMSS 'Invalid column name' - sql

Before you reprimand me about how 'this has been asked here:', I'd like to point out I did indeed google. I even went to page 3 in some cases. shudders
So here's the deal:
I'm trying to audit a database we have, setting triggers for UPDATE, INSERT, DELETE statements for several tables. The triggers are created, and linked, succesfully. Each trigger executes a stored-procedure that inserts required data into our tick_audit table.
This information is:
user_account; to store who changed something
client_id; to store which client had their data changed
date_time; the date of the edit
table_name; the name of the table that was changed
table_record_id; the id of the record that was changed
descr; a description of why something was changed
remote_ip_address; so we can keep tabs where something was changed (internal or external)
The table also has a PRIMARY_KEY, AUTO_INCREMENT id field.
When I try to create the stored-procedure
create procedure update_tick_user
#UserId varchar(32),
#ClientId varchar(32),
#Table varchar(64),
#TableRecord varchar(512),
#Descr varchar(128),
#RemoteIP varchar(16)
as
begin
insert into tick_audit ('user_account', 'client_id', 'date_time', 'table_name', 'table_record_id', 'descr', 'remote_ip_address')
values
(#UserId, #ClientId, getdate(), #Table, #TableRecord, #Descr, #RemoteIP)
end;
I get the following error(s):
Msg 207, Level 16, State 1, Procedure update_tick_user, Line 10
Invalid column name 'user_account'.
This repeats for each column. When I run
exec sp_columns tick_audit
I get all the columns from tick_audit, and even copying their names into the column-fields for the insert, I get the above-mentioned errors. I even get the errors when I simply run
insert into tick_audit
('user_account', 'client_id', 'date_time', 'table_name', 'table_record_id', 'descr', 'remote_ip_address')
values
('', '', getdate(), '', '', '', '')
Whenever I try an insert, update or delete on a different table, I get no errors. Is there anything I could try to find out if there's a fault in my table, or some super-secret hocus-pocus, ritual-esque method?
Here's what I've tried so far:
Drop the table (On my feet, many many times), re-create it.
Google for three hours
Asked my co-workers
Put on my thinking cap
Check if columns actually exists (through exec, select)
Crossing my fingers and hoping someone can help me.

Remove ' to make insert as below
insert into tick_audit (user_account, client_id, date_time, table_name, table_record_id, descr, remote_ip_address)
values (#UserId, #ClientId, getdate(), #Table, #TableRecord, #Descr, #RemoteIP)

Use brackets instead of quotes:
insert into tick_audit ([user_account], [client_id], [date_time], [table_name], [table_record_id], [descr], [remote_ip_address])
values (#UserId, #ClientId, getdate(), #Table, #TableRecord, #Descr, #RemoteIP)
Single quote are for literals. For delimiting object names you should use brackets or double quotes but you can use double quotes only when QUOTED_IDENTIFIER is set to ON.

Do not use single quotes arround column names.
create procedure update_tick_user
#UserId varchar(32),
#ClientId varchar(32),
#Table varchar(64),
#TableRecord varchar(512),
#Descr varchar(128),
#RemoteIP varchar(16)
as
begin
insert into tick_audit (user_account, client_id, date_time, table_name, table_record_id, descr, remote_ip_address)
values
(#UserId, #ClientId, getdate(), #Table, #TableRecord, #Descr, #RemoteIP)
end;

Related

Create a procedure to insert multiple values into a table, using a single variable

Goal: To create a procedure to insert multiple values into a table, using a single variable.
Challenge: Instead of making multiple hits in the same table, I have created a single variable (#SQL) and stored multiple columns (fm_id and shdl_id ) results in it but I am unable to use this single variable in the insert statement.
Code:
create proc abc
(
#org_id numeric(10,0),
#shdl_id numeric(10,0),
#usr_id numeric(10,0),
#tst_id numeric(10,0)
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #SQL NUMERIC(10);
SET #SQL= (SELECT fm_id,#shdl_id FROM [dbo].[students] WHERE ORG_ID=#org_id AND shdl_id=#shdl_id AND TST_ID=#tst_id)
INSERT INTO [USER]
SELECT org_id,#usr_id,TST_ID,login_name,#SQL FROM [students] WHERE ORG_ID=#org_id AND shdl_id=#shdl_id AND TST_ID=#tst_id
END
GO
Error :
Msg 213, Level 16, State 1, Procedure abc, Line 14 [Batch Start Line
94] Column name or number of supplied values does not match table
definition.
First you need to make your SELECT return only one value into the variable. There's no point selecting #shdl_id because you already know it?
DECLARE #pFMID NUMERIC(10);
SELECT #pFMID = MAX(fm_id) FROM [dbo].[students] WHERE ORG_ID=#org_id AND shdl_id=#shdl_id AND TST_ID=#tst_id);
Then because you're not inserting a value into every column in the user table you need to explicitly state which columns to fill. Replace x1..x5 below with real column names (in the order the SELECT has them)
INSERT INTO [USER](x1,x2,x3,x4,x5)
-- ^^^^^^^^^^^^^^^
-- REPLACE THESE WITH REAL NAME
SELECT org_id,#usr_id,TST_ID,login_name,#pFMID FROM [students] WHERE ORG_ID=#org_id AND shdl_id=#shdl_id AND TST_ID=#tst_id
END
GO
And as Uueerdo pointed out, this first query is a bit of a waste of time, we can write this:
create proc abc
(
...
)
AS
BEGIN
INSERT INTO [USER](x1,x2,x3,x4,x5)
SELECT org_id,#usr_id,TST_ID,login_name,fm_id FROM [students] WHERE ORG_ID=#org_id AND shdl_id=#shdl_id AND TST_ID=#tst_id
-- ^^^^^
-- look!
You can only get away with leaving the column list off an INSERT if you're inserting the same number of columns the table has:
CREATE TABLE x(col1 INT, col2 INT);
INSERT INTO x VALUES (1,2) -- works
INSERT INTO x VALUES (1) -- fails: which column should have the 1?
INSERT INTO x(col1) VALUES (1) -- works: col1 shall have the 1

Error converting varchar to bigint

I got the error where my data type is varchar, then I want to insert value/input in textboxt = 'smh85670s'.
It appear to be error. As far as I know varchar can accept characters and numbers, but why does it keep throwing this error?
If I insert value '123456' the table can accept that value.
Please guide me. What data type should I use?
Assuming that you are using Stored procedures (which have an insert query) or directly firing an insert query into DB, you must be sending all data as parameters like say #param1, #param2,...
Your insert query will be like
INSERT INTO Sometable ( Amount, textbox,... )
SELECT #param1, #param2 ,...
Just add a cast in this query to make it work
INSERT INTO Sometable ( Amount, textbox,... )
SELECT #param1, CAST(#param2 as varchar),...

How to pass comma separated list in sp_executesql

I want to use IN opeartor in sp_executesql, but facing the error that Incorrect syntax near '#TagIndexListToAdjust'.
This error is due to single quotes at both side of the parameter value '(1,2,3)'.
I need to fix it with in only the sp_executesql as this query is generated by C# model class.
USE [master]
GO
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[Persons]') AND type in (N'U'))
DROP TABLE [dbo].Persons
GO
USE [master]
GO
CREATE TABLE Persons
(
commaList nvarchar(MAX),
);
insert into Persons values ('1')
insert into Persons values ('2')
insert into Persons values ('3')
GO
exec sp_executesql N'
Select *
from Persons
where commaList in #TagIndexListToAdjust',
N'#TagIndexListToAdjust varchar(67)',
#TagIndexListToAdjust='(1,2,3)'
Any help will be appriciated in fixing the error.
Use 2 quotation marks.. one for escaping the other one.

How do I use an INSERT statement's OUTPUT clause to get the identity value?

If I have an insert statement such as:
INSERT INTO MyTable
(
Name,
Address,
PhoneNo
)
VALUES
(
'Yatrix',
'1234 Address Stuff',
'1112223333'
)
How do I set #var INT to the new row's identity value (called Id) using the OUTPUT clause? I've seen samples of putting INSERTED.Name into table variables, for example, but I can't get it into a non-table variable.
I've tried OUPUT INSERTED.Id AS #var, SET #var = INSERTED.Id, but neither have worked.
You can either have the newly inserted ID being output to the SSMS console like this:
INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')
You can use this also from e.g. C#, when you need to get the ID back to your calling app - just execute the SQL query with .ExecuteScalar() (instead of .ExecuteNonQuery()) to read the resulting ID back.
Or if you need to capture the newly inserted ID inside T-SQL (e.g. for later further processing), you need to create a table variable:
DECLARE #OutputTbl TABLE (ID INT)
INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID INTO #OutputTbl(ID)
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')
This way, you can put multiple values into #OutputTbl and do further processing on those. You could also use a "regular" temporary table (#temp) or even a "real" persistent table as your "output target" here.

Column name or number of supplied values does not match table definition

In the SQL Server, I am trying to insert values from one table to another by using the below query:
delete from tblTable1
insert into tblTable1 select * from tblTable1_Link
I am getting the following error:
Column name or number of supplied values does not match table definition.
I am sure that both the tables have the same structure, same column names and same data types.
They don't have the same structure... I can guarantee they are different
I know you've already created it... There is already an object named ‘tbltable1’ in the database
What you may want is this (which also fixes your other issue):
Drop table tblTable1
select * into tblTable1 from tblTable1_Link
I want to also mention that if you have something like
insert into blah
select * from blah2
and blah and blah2 are identical keep in mind that a computed column will throw this same error...
I just realized that when the above failed and I tried
insert into blah (cola, colb, colc)
select cola, colb, colc from blah2
In my example it was fullname field (computed from first and last, etc)
for inserts it is always better to specify the column names see the following
DECLARE #Table TABLE(
Val1 VARCHAR(MAX)
)
INSERT INTO #Table SELECT '1'
works fine, changing the table def to causes the error
DECLARE #Table TABLE(
Val1 VARCHAR(MAX),
Val2 VARCHAR(MAX)
)
INSERT INTO #Table SELECT '1'
Msg 213, Level 16, State 1, Line 6
Insert Error: Column name or number of
supplied values does not match table
definition.
But changing the above to
DECLARE #Table TABLE(
Val1 VARCHAR(MAX),
Val2 VARCHAR(MAX)
)
INSERT INTO #Table (Val1) SELECT '1'
works. You need to be more specific with the columns specified
supply the structures and we can have a look
The problem is that you are trying to insert data into the database without using columns. SQL server gives you that error message.
Error: insert into users values('1', '2','3') - this works fine as long you only have 3 columns
If you have 4 columns but only want to insert into 3 of them
Correct: insert into users (firstName,lastName,city) values ('Tom', 'Jones', 'Miami')
Beware of triggers. Maybe the issue is with some operation in the trigger for inserted rows.
Dropping the table was not an option for me, since I'm keeping a running log. If every time I needed to insert I had to drop, the table would be meaningless.
My error was because I had a couple columns in the create table statement that were products of other columns, changing these fixed my problem. eg
create table foo (
field1 as int
,field2 as int
,field12 as field1 + field2 )
create table copyOfFoo (
field1 as int
,field2 as int
,field12 as field1 + field2) --this is the problem, should just be 'as int'
insert into copyOfFoo
SELECT * FROM foo
The computed columns make the problem.
Do not use SELECT *. You must specify each fields after SELECT except computed fields
some sources for this issues are as below
1- Identity column ,
2- Calculated Column
3- different structure
so check those 3 , i found my issue was the second one ,
For me the culprit is int value assigned to salary
Insert into Employees(ID,FirstName,LastName,Gender,Salary) values(3,'Canada', 'pa', 'm',15,000)
in salary column When we assign 15,000 the compiler understand 15 and 000.
This correction works fine for me.
Insert into Employees(ID,FirstName,LastName,Gender,Salary) values(4,'US', 'sam', 'm',15000)
Update to SQL server 2016/2017/…
We have some stored procedures in place to import and export databases.
In the sp we use (amongst other things) RESTORE FILELISTONLY FROM DISK where we create a
table "#restoretemp" for the restore from file.
With SQL server 2016, MS has added a field SnapshotURL nvarchar(360) (restore url Azure) what has caused the error message.
After I have enhanced the additional field, the restore has worked again.
Code snipped (see last field):
SET #query = 'RESTORE FILELISTONLY FROM DISK = ' + QUOTENAME(#BackupFile , '''')
CREATE TABLE #restoretemp
(
LogicalName nvarchar(128)
,PhysicalName nvarchar(128)
,[Type] char(1)
,FileGroupName nvarchar(128)
,[Size] numeric(20,0)
,[MaxSize] numeric(20,0)
,FileID bigint
,CreateLSN numeric(25,0)
,DropLSN numeric(25,0) NULL
,UniqueID uniqueidentifier
,ReadOnlyLSN numeric(25,0)
,ReadWriteLSN numeric(25,0)
,BackupSizeInByte bigint
,SourceBlockSize int
,FilegroupID int
,LogGroupGUID uniqueidentifier NULL
,DifferentialBaseLSN numeric(25,0)
,DifferentialbaseGUID uniqueidentifier
,IsReadOnly bit
,IsPresent bit
,TDEThumbprint varbinary(32)
-- Added field 01.10.2018 needed from SQL Server 2016 (Azure URL)
,SnapshotURL nvarchar(360)
)
INSERT #restoretemp EXEC (#query)
SET #errorstat = ##ERROR
if #errorstat <> 0
Begin
if #Rueckgabe = 0 SET #Rueckgabe = 6
End
Print #Rueckgabe
Check your id. Is it Identity? If it is then make sure it is declared as ID not null Identity(1,1)
And before creating your table , Drop table and then create table.
The problem I had that caused this error was that I was trying to insert null values into a NOT NULL column.
I had the same problem, and the way I worked around it is probably not the best but it is working now.
It involves creating a linked server and using dynamic sql - not the best, but if anyone can suggest something better, please comment/answer.
declare #sql nvarchar(max)
DECLARE #DB_SPACE TABLE (
[DatabaseName] NVARCHAR(128) NOT NULL,
[FILEID] [smallint] NOT NULL,
[FILE_SIZE_MB] INT NOT NULL DEFAULT (0),
[SPACE_USED_MB] INT NULL DEFAULT (0),
[FREE_SPACE_MB] INT NULL DEFAULT (0),
[LOGICALNAME] SYSNAME NOT NULL,
[DRIVE] NCHAR(1) NOT NULL,
[FILENAME] NVARCHAR(260) NOT NULL,
[FILE_TYPE] NVARCHAR(260) NOT NULL,
[THE_AUTOGROWTH_IN_KB] INT NOT NULL DEFAULT(0)
,filegroup VARCHAR(128)
,maxsize VARCHAR(25)
PRIMARY KEY CLUSTERED ([DatabaseName] ,[FILEID] )
)
SELECT #SQL ='SELECT [DatabaseName],
[FILEID],
[FILE_SIZE_MB],
[SPACE_USED_MB],
[FREE_SPACE_MB],
[LOGICALNAME],
[DRIVE],
[FILENAME],
[FILE_TYPE],
[THE_AUTOGROWTH_IN_KB]
,filegroup
,maxsize FROM OPENQUERY('+ QUOTENAME('THE_MONITOR') + ','''+ ' EXEC MASTER.DBO.monitoring_database_details ' +''')'
exec sp_executesql #sql
INSERT INTO #DB_SPACE(
[DatabaseName],
[FILEID],
[FILE_SIZE_MB],
[SPACE_USED_MB],
[FREE_SPACE_MB],
[LOGICALNAME],
[DRIVE],
[FILENAME],
[FILE_TYPE],
THE_AUTOGROWTH_IN_KB,
[filegroup],
maxsize
)
EXEC SP_EXECUTESQL #SQL
This is working for me now.
I can guarantee the number of columns and type of columns returned by the stored procedure are the same as in this table, simply because I return the same table from the stored procedure.
In my case, I had:
insert into table1 one
select * from same_schema_as_table1 same_schema
left join...
and I had to change select * to select same_schema.*.
You're missing column name after TableName in insert query:
INSERT INTO TableName**(Col_1,Col_2,Col_3)** VALUES(val_1,val_2,val_3)
In my case the problem was that the SP I was executing returned two result sets, and only the second result set was matching the table definition.