Identity Insert Problem - sql

I am trying to run this script:
SET IDENTITY_INSERT dbo.Message ON
INSERT INTO dbo.Message
SELECT (Values I want to insert)
and when I do I still get the error
*An explicit value for the identity column in table 'dbo.Message' can only be specified when a column list is used and IDENTITY_INSERT is ON.*
What am I doing wrong?

The key to your error is "when a column list is used". You want:
SET IDENTITY_INSERT dbo.Message ON
INSERT INTO dbo.Message (column1, column2, ...) -- Added column list here
SELECT (Values I want to insert)

You need to do just as the error message says. Format your code like:
INSERT INTO dbo.Message
(col1, col2, col3, col4)
SELECT Col1, col2, col3, col4
FROM OtherTable
You need the list of fields after the INSERT line, and you need to specify the field names in your SELECT - SELECT * won't work.

You have to mention all the columns Name in both Insert Statement and in select clause.
Some thing like this.
Insert Into tbl
(
[col1],
[col2]
)
SELECT
[col1],
[col2]

Related

INSERT INTO tableName SELECT * INTO tabkeName FROM tableName

How will this below query execute and is there a better way to write this query?
INSERT INTO tableName
SELECT *
INTO tableName
FROM tableName
I would use:
INSERT INTO tableName (col1, col2, col3)
SELECT col1, col2, col3
FROM someOtherTable;
Note that you should generally always explicitly specify which columns you want both for the insert and the select. While your code might run as is, it is prone to breaking should the structure for either table change in the future.

Insert multiple rows in a single query using results of a select statement

I am looking for a compact way to do this - insert multiple rows into a table with values from multiple columns of a row from another table. My destination table is really a list with a single column:
declare #stringList table
(
val nvarchar(100)
)
This is how we can insert multiple rows:
INSERT INTO #stringList ( val ) VALUES
Val1, Val2, Val3, ...
This is how we insert from a select:
INSERT INTO #stringList
SELECT col1 FROM table1 where id=something
But I cannot seem to find a way to use both at the same time.
I can select from one column:
insert into #stringList (val)
select col1 from table1 where id=something
But it doesn't extend to multiple columns:
insert into #stringList (val)
select col1, col2 from table1 where id=something
--The select list for the INSERT statement contains more items than the insert list. The number of SELECT values must match the number of INSERT columns.
I have tried various ways including using parentheses, but the syntax is not accepted:
insert into #stringList (val)
(select col1 from table1 where id=something,
select col2 from table1 where id=something
Any idea if what I want is doable?
You can unpivot using cross apply:
insert into #stringList (val)
select v.col
from table1 t1 cross apply
(values (t1.col1), (t1.col2)) v(col)
where t1.id = something;

select * Within an Insert Statement

I'm currently inserting into a table with the following prefix but also manaully set what i want in the last 2 columns ( 1,getdate() )
Insert into [Table1]
select col1,col2,col3, 1,getdate()
from [table2]
Issue is there are loads of columns and causing a mess in the SP.
I've tried to rewrite the statement with...
Insert Into [table1]
Select * from [Table2]
But I also need to take into consideration I want to manually write into those 2 columns..
Is there a way of doing this ?
Many Thanks
This might solve your issue:
Insert into [Table1]
select col1, col2, col3, '1' as [col4] , getdate() as [col5] from [table2]
Two points. First, when using insert you should always be in the habit of naming the columns for the insert:
Insert into [Table1](col1, col2, col3, col4, col5)
select col1, col2, col3, 1, getdate()
from [table2];
Second, you do not have to put getdate() in the insert. Let the database do the work for you with a default value:
create table table1 . . .
col5 date default getdate()
);

Convert each column of a record into separate record

I have a record:
DECLARE #Tbl AS TABLE(Col1 VARCHAR(10), Col2 VARCHAR(10), Col3 VARCHAR(10));
INSERT INTO #Tbl
VALUES('Val1', 'Val2', 'Val3')
-- Source Record
SELECT Col1, Col2, Col3 FROM #Tbl
Result: Val1 Val2 Val3
I want result of each column as separate two column records like first column will become the title of source column and second column should be the value of source column like the result of below query in which I have achieved the result by UNION ALL :
--Query for Target Result
SELECT 'Col1' AttributeTitle, CONVERT(VARCHAR, Col1) AttributeValue FROM #Tbl
UNION ALL SELECT 'Col2' AttributeTitle, CONVERT(VARCHAR, Col2) AttributeValue FROM #Tbl
UNION ALL SELECT 'Col3' AttributeTitle, CONVERT(VARCHAR, Col3) AttributeValue FROM #Tbl
Problem in this query is I have to explicitly define the columns, is there any way that it should dynamically get the columns names and their values?
You could use UNPIVOT but you still need to know the names of the columns.
SELECT ColumnName, ValueName
FROM (SELECT * FROM #Tbl) AS Data
UNPIVOT
( ValueName
FOR ColumnName IN (Col1, Col2, Col3)
) AS PivottedOutput
I like the apply method for unpivoting in SQL Server:
select v.*
from #tbl t cross apply
(values ('col1', col1),
('col2', col2),
('col3', col3)
) v(AttributeTitle, AttributeValue);
This simplifies the query but it does not directly answer the question.
If you want a variable number of columns, then you are going to have to use dynamic SQL. This is a bit cumbersome on a real table. However, with a table variable or a temporary table, you have the additional issue of scoping rules -- the name of the table will not be in scope when you execute the statement.

Grouping result according to one column in sql

I have a sql statement like
SELECT column1, column2,column3, column4 FROM table1 GROUP BY column3
or
SELECT * FROM table1 GROUP BY column3
I want a result which is grouped according to column3 and also has other columns. But it gives an error.What should I do? thanks..
If i understand your expected end result correctly,
try using ORDER instead of GROUP
if however that does not give you your desired output, i apologize.
SELECT column1, column2,column3, column4
FROM table1
ORDER BY column3
SELECT *
FROM table1
ORDER BY column3
What you are trying to do is an undefined behavior. When you specify GROUP BY on a column, there can be multiple values in other columns. There is no sane way for the database to figure out what values to show.
PARTITION is probably what you are looking for. Check this link: http://msdn.microsoft.com/en-us/library/ms189461.aspx
Grouping applies to aggregate functions such as SUM(). It doesn't make sense to group individual fields.
SELECT SUM(col1), MAX(col2), col3 from t1 group by col3
I haven't understood your question exactly and what for you need this query, but maybe you can use this one:
/*t-sql example*/
create table #T (id int identity(1,1), col1 varchar(5), col2 varchar(5), col3 varchar(6))
insert #T (col1,col2,col3) values ('aaa','a1e','group1')
insert #T (col1,col2,col3) values ('bbb','a2e','group1')
insert #T (col1,col2,col3) values ('ccc','a3e','group1')
insert #T (col1,col2,col3) values ('ddd','a4e','group2')
insert #T (col1,col2,col3) values ('eee','a5e','group2')
insert #T (col1,col2,col3) values ('fff','a6e','group3')
select id,col1,col2,#T.col3,subq.cnt from #T
join
(select col3, COUNT(*) as 'cnt' from #T group by col3) as subq
on
#T.col3 = subq.col3
I have used sub-query, but you can use temporary table or WITH. Also, I have used "count" for aggregation just for example.
Max