SELECT * INTO FAILS - sql

I have following table structure :
CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST]
(
[MAPPING_ID] [int] IDENTITY(1,1) NOT NULL,
[USER_ID] [varchar](50) NULL,
[USER_EMAIL_ID] [varchar](100) NULL,
[USER_CREATED_DATE] [datetime] NULL,
[USER_IS_ACTIVE] [bit] NULL,
CONSTRAINT [PK_UTS_USERCLIENT_MAPPING_USER_LIST]
PRIMARY KEY CLUSTERED ([MAPPING_ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
In stored procedure I have this code:
ALTER PROCEDURE [dbo].[PROC_UTS_USER_CLIENTMAPPING_LIST_SET]
(#RETURN_CODE INT OUTPUT,
#RETURN_MESSAGE NVARCHAR(512) OUTPUT,
#XML_USER_LIST xml)
AS
BEGIN TRY
SELECT
ROW_NUMBER() OVER(ORDER BY x.value('USERNAME[1]','nvarchar(50)')) AS MAPPING_ID,
x.value('USERNAME[1]', 'nvarchar(50)') as USER_ID,
x.value('EMAILID[1]', 'nvarchar(50)') as USER_EMAIL_ID,
x.value('CREATEDDATE[1]', 'datetime') as USER_CREATED_DATE,
x.value('ISACTIVE[1]', 'bit') as USER_IS_ACTIVE
INTO #tempXML
FROM #XML_USER_LIST.nodes('/DocumentElement/dtLstUsers') AS TEMPTABLE(x)
SELECT *
INTO UTS_USERCLIENT_MAPPING_USER_LIST
FROM #tempXML
END TRY
My problem is that above stored procedure is not inserting data into UTS_USERCLIENT_MAPPING_USER_LIST from #tempXML table.
I have ensured that #tempXML table contains values.

There are a few flaws in your query:
1 - you are trying to insert an IDENTITY value without setting IDENTITY_INSERT ON before inserting into your table, and then set it to OFF
SET IDENTITY_INSERT UTS_USERCLIENT_MAPPING_USER_LIST ON
2 - SELECT * INTO table will assume the table doesn't exist and will try to create it there, will fail -> need to use INSERT INTO SELECT
INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (cols)
SELECT cols
FROM #temp
3 - you are calculating the MAPPING_ID with ROW_NUMBER function which will start from 1 to n (where n is number of nodes you have in xml)every time, but your table has a PRIMARY KEY on MAPPING_ID column which implies is UNIQUE so 2nd time you want to insert MAPPING_ID 1, it will fail.
4 - If you have a CATCH block which is empty, it will hide your errors
Now, the solution without really understanding your needs regarding MAPPING_ID column, is to change the insert statement there to:
INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST ([USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE])
SELECT [USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE]
FROM #tempXML
OR if you have a valid MAPPING_ID found from xml somehow:
SET IDENTITY_INSERT UTS_USERCLIENT_MAPPING_USER_LIST ON
INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST ([MAPPING_ID], [USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE])
SELECT [MAPPING_ID], [USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE]
FROM #tempXML
SET IDENTITY_INSERT UTS_USERCLIENT_MAPPING_USER_LIST OFF

As per my understanding you need to mentioned all the column name apart from Mapping_ID. see below code
INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (
USER_ID,
USER_EMAIL_ID,
USER_CREATED_DATE,
USER_IS_ACTIVE)
select USER_ID,
USER_EMAIL_ID,
USER_CREATED_DATE,
USER_IS_ACTIVE
from #tempXML

Looks like you need to turn on IDENTITY_INSERT as Sparky has suggested.

Also a possible solution is that you aren't using IDENTITY column at all - in case it's not needed. (In case this table is getting the data only from this store procedure there is no need to use IDENTITY column):
CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST](
[MAPPING_ID] [int] NOT NULL,
[USER_ID] [varchar](50) NULL,
[USER_EMAIL_ID] [varchar](100) NULL,
[USER_CREATED_DATE] [datetime] NULL,
[USER_IS_ACTIVE] [bit] NULL,
CONSTRAINT [PK_UTS_USERCLIENT_MAPPING_USER_LIST] PRIMARY KEY CLUSTERED
(
[MAPPING_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Real problem was,
SELECT * INTO always creates new table.
So I needed to drop the existing table before its creation.
When I :
DROP TABLE UTS_USERCLIENT_MAPPING_USER_LIST
SELECT *
INTO UTS_USERCLIENT_MAPPING_USER_LIST
FROM #tempXML
Then it worked.
Thank You.

Couldn't you just skip the temporary table altogether?
-- TRUNCATE TABLE HERE, IF NEED BE
INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (<ColumnList>)
SELECT
ROW_NUMBER() OVER(ORDER BY x.value('USERNAME[1]','nvarchar(50)')) AS MAPPING_ID,
x.value('USERNAME[1]', 'nvarchar(50)') as USER_ID,
x.value('EMAILID[1]', 'nvarchar(50)') as USER_EMAIL_ID,
x.value('CREATEDDATE[1]', 'datetime') as USER_CREATED_DATE,
x.value('ISACTIVE[1]', 'bit') as USER_IS_ACTIVE
FROM #XML_USER_LIST.nodes('/DocumentElement/dtLstUsers') AS TEMPTABLE(x)

Related

Inserto into ( Select ) with not auto increment

Have two tables
CREATE TABLE [dbo].[TABELAA]
(
[ID] [bigint] NOT NULL,
[PodatakA] [nvarchar](50) NULL,
[PodatakB] [nvarchar](50) NULL,
CONSTRAINT [PK_TABELAA]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TABELAB]
(
[PodatakX] [nvarchar](50) NULL,
[PodatakY] [nvarchar](50) NULL
) ON [PRIMARY]
GO
I need to insert value from tabelaB to tabelaA with autogenerating ID in tabelaA so I need something like this. But this would be great if there is only one row. I'm talking about thousands of rows where it should auto generate id exact like AutoIncrement (1)
Useless try where I think I should use OVER
INSERT INTO TABELAA
SELECT
(SELECT MAX(id) + 1 FROM TabelaA) AS Id, *
FROM
tabelaB
You are looking for the IDENTITY:
CREATE TABLE [dbo].[TABLAAA](
[ID] [bigint] IDENTITY(1, 1) PRIMARY KEY, -- NOT NULL is handled by PRIMARY KEY
[PodatakA] [nvarchar](50) NULL,
[PodatakB] [nvarchar](50) NULL
);
INSERT INTO TABLEAA (PodatakA, PodatakB)
SELECT PodatakA, PodatakB
FROM TABLEBB;
I agree with Rahul's comment and Gordon that if you can modify your schema it would make the most sense to add an Identity Column. However if you cannot you can still accomplish what you want using a couple of methods.
One method is get the MAX ID of TableAA and then add a ROW_NUMBER() to it like so:
INSERT INTO TableAA (ID, PodatakA, PodatakB)
SELECT
m.CurrentMaxId + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
,b.PodatakA
,b.PodatakB
FROM
TableAB b
CROSS APPLY (
SELECT ISNULL(MAX(Id),0) as CurrentMaxId
FROM
TableAA) m
Again this would be work around the most ideal solution is to specify IDENTITY
Also this is susceptible to problems due to simultaneous writes and other scenarios in a heavy traffic DB.

Conversion failed when converting the nvarchar value 'newValue' to data type int

I'm pretty sure that I am inserting the correct data. I have drop all Indexes, Triggers, Constraint to make sure nothing is intervening my insert.
Here's the catch: the field that I'm trying to insert to previously has a datatype of int but changed to nvarchar(100) later. Does anybody know where should I look into?
This is the table structure
CREATE TABLE [dbo].[myTable.Values](
[myTableId] [bigint] NOT NULL,
[myTableCode] [nvarchar](100) NOT NULL,
[Code] [nvarchar](100) NOT NULL,
[value] [nvarchar](250) NOT NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
[UpdateById] [bigint] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
CONSTRAINT [PK_myTable.Values] PRIMARY KEY CLUSTERED
(
[myTableCode] ASC,
[Code] ASC,
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, `ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]`
) ON [PRIMARY]
and this is the script for insert
INSERT INTO [dbo].[myTable.Values] (
[myTableId]
,[myTableCode]
,[Code]
,[value]
,[UpdateById]
,[UpdateDate]
)
VALUES (
581
,'myParentTableCODE'
,'myTableNewCode'
,'myTableNewCode'
,5197
,getdate()
)
Thanks for looking into this, I have found out one of our View is using "WITH SCHEMABINDING" clause. And that view is Casting the field "Code" as int. Here is the view.
CREATE VIEW [dbo].[vSomeView] WITH SCHEMABINDING
AS
SELECT
id,
CAST(Code AS INT) AS [Code],
myTableCode
FROM dbo.[myTable.Values]
WHERE myTableCode LIKE '%ABC'
AND ISNUMERIC(Code) = 1
it seems yourinsertion code is not complete, you should to add another field and assign value to it,the field is IsDefaultObsolete, then try this code for insert :
INSERT INTO [dbo].[myTable.Values] (
[myTableId]
,[myTableCode]
,[Code]
,[value]
,[IsDefaultObsolete]
,[UpdateById]
,[UpdateDate]
)
VALUES (
581
,'myParentTableCODE'
,'myTableNewCode'
,'myTableNewCode'
0,--THIS MAY BE 0 OR 1 DEPENDING YOU
,5197
,getdate()
)

use sql stored procedure to insert data which is returned from a query stored in a table

sql server 2005
I have a stored procedure which I used to insert data into a table. Some of the data will need to come from the results of executing a query that is stored in a separate table.
The main problem that I keep hitting is not being able to properly execute the returned query. I have tried creating several functions over the past couple of days based on other posts that I have read, but I keep hitting sql errors with exec, execute, sp_executesql, etc.
I am going to paste several scripts that you can use to replicate my environment. I am hoping that someone can please provide an actual code sample which will execute the returned query for use within the stored proc insert function.
Thank you!!!
CREATE TABLE [dbo].[CLIENT](
[cli_id] [int] IDENTITY(1,1) NOT NULL,
[cli_first_name] [varchar](100) NULL,
CONSTRAINT [PK__CLIENT__07F6335A] PRIMARY KEY CLUSTERED
(
[cli_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT INTO CLIENT (cli_first_name, cli_last_name) values ('tom', 'smith');
go
CREATE TABLE [dbo].[ASSESSMENT_DATALABEL_LIST](
[adl_ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[BoundName] [nvarchar](50) NOT NULL,
[Query] [ntext] NOT NULL,
[KeyFieldName] [nvarchar](50) NOT NULL,
[Status] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_ASSESSMENT_DATALABEL_LIST] PRIMARY KEY CLUSTERED
(
[adl_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT INTO ASSESSMENT_DATALABEL_LIST (Name, BoundName, Query, KeyFieldName, Status)
values ('Name, First', 'cli_first_name', 'select IsNull(cli_first_name,'''') as cli_first_name FROM CLIENT WHERE cli_id = #KeyFieldValue', 'cli_ID', 'Active')
go
INSERT INTO ASSESSMENT_DATALABEL_LIST (Name, BoundName, Query, KeyFieldName, Status)
values ('Name, Last', 'cli_last_name', 'select IsNull(cli_last_name,'''') as cli_last_name FROM CLIENT WHERE cli_id = #KeyFieldValue', 'cli_ID', 'Active')
go
CREATE TABLE [dbo].[Item_Source]
(
[Item_ID] [int] IDENTITY(1,1) NOT NULL,
[ItemType] [nvarchar](50) NOT NULL,
[ItemCaption] [nvarchar] (50) NULL,
[adl_ID] [int] NOT NULL
)
go
INSERT INTO Item_Source
(ItemType, ItemCaption, adl_ID) values
('DATALABEL', 'First Name',1)
go
INSERT INTO Item_Source
(ItemType, ItemCaption, adl_ID) values
('DATALABEL', 'Last Name',2)
go
CREATE TABLE [dbo].[Item_Destination]
(
[ItemType] [nvarchar](50) NOT NULL,
[ItemCaption] [nvarchar] (50) NULL,
[ItemValue] [nvarchar](50) NULL
)
go
CREATE PROCEDURE [dbo].[spInsertStuff]
#cli_id int
AS
INSERT INTO Item_Destination
(ItemType, ItemCaption, ItemValue)
SELECT
ItemType, ItemCaption, [[[ VALUE OF EXECUTED QUERY FROM ADL TABLE --- dbo.FunctionToGetResultsOfStoredQuery(Item_Source.adl_id, #cli_id) ]]]
FROM Item_Source WHERE Item_Source.Item_ID IN (1,2)
-- this insert will insert both Item_Source rows into Item_Dest with one call. The first row should have an ItemValue of Tom, the second row should have an ItemValue of Smith
GO
You may check this fiddle
The code of the Stored Procedure is:
CREATE PROCEDURE [dbo].[spInsertStuff]
#cli_id int
AS
DECLARE #SQL AS VARCHAR(MAX)
DECLARE #ADL_ID AS INT
DECLARE MyCURSOR
CURSOR FOR
SELECT QUERY, ADL_ID FROM ASSESSMENT_DATALABEL_LIST
OPEN MyCURSOR
FETCH NEXT FROM MyCURSOR INTO #SQL, #ADL_ID
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = REPLACE(#SQL,'#KeyFieldValue',#cli_id)
DECLARE #Temp AS TABLE ([Value] [nvarchar](50))
INSERT INTO #Temp
EXEC (#SQL)
INSERT INTO Item_Destination
(ItemType, ItemCaption, ItemValue)
SELECT
ItemType, ItemCaption, (SELECT [Value] FROM #Temp)
FROM Item_Source
WHERE Item_Source.adl_ID = #ADL_ID
DELETE FROM #Temp
FETCH NEXT FROM MyCURSOR INTO #SQL, #ADL_ID
END
CLOSE MyCURSOR
DEALLOCATE MyCURSOR
GO

Query to update rows and then create a table if it does not exist

I have two different things to happen at once.., basically I need to insert two new records in a table if they are not already there... and for sure they will always have the same ID and Name (i did this) but then immediately after that i need to check if a table existst and if it does not create it.. (but if it does exist I DO NOT want to drop it just leave it alone).
Please see my code below.. Can you help me with the checking of the table existing or not? and if you see a room on improvement please do..
Thank you
--ADD LOCKS
BEGIN TRAN
IF EXISTS (SELECT myID, myName
FROM myTable
WHERE myID = 7 AND myName = 'Pedro')
SELECT 1
ELSE
INSERT INTO myTable (myID , myName) values ( 7, 'Pedro')
IF EXISTS (SELECT myID, myName
FROM myTable
WHERE myID = 8 AND myName = 'Joseph')
SELECT 1
ELSE
INSERT INTO myTable (myID , myName) values ( 8, 'Joseph')
COMMIT
--NOW BELOW I WANT TO DO THE CREATION OF A TABLE IF IT DOES NOT EXIST
NOT SURE HOW TO CHECK IT.. BUT KNOW HOW TO CREATE IT
--IF TABLE DOES NOT EXIST DO THE FOLLOWING
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[myTable](
[myID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar(MAX)] NOT NULL
CONSTRAINT [PK_myTable] PRIMARY KEY CLUSTERED
(
[myID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--ELSE DONT DO NOTHING
As per my knowledge, you have check whether the table exists or not first and create it before inserting if it doesn't exist. Hope the below query might be of some use for you.
IF NOT EXISTS (SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID(N'[dbo].[myTable]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN
CREATE TABLE [dbo].[myTable]
(
[myID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar(MAX)] NOT NULL
CONSTRAINT [PK_myTable] PRIMARY KEY CLUSTERED
( [myID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY] ) ON [PRIMARY]
END
IF NOT EXISTS (SELECT myID, myName FROM myTable WHERE myID = 7 AND myName = 'Pedro')
BEGIN
INSERT INTO myTable (myID , myName) values ( 7, 'Pedro')
END
IF NOT EXISTS (SELECT myID, myName FROM myTable WHERE myID = 8 AND myName = 'Joseph')
BEGIN
INSERT INTO myTable (myID , myName) values ( 8, 'Joseph')
END
Edit: Should also note, this will not work without turning IDENTITY_INSERT ON. Because the myID column is an identity field, the values attempting to be inserted will fail.
For inserting the records cleaner script would be:
IF NOT EXISTS (SELECT 1 FROM myTable WHERE ...)
BEGIN
-- Insert record
END
And for checking if a table exists:
Check if table exists in SQL Server
IF (NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TheSchema' AND TABLE_NAME = 'TheTable'))
BEGIN
-- Insert table
END
You might want to switch the order of these statements so you don't query a table that may not exist.

Grouping data in SQL Server

Please Consider the following table :
As you can see the Name column has some repeated values with is a group like
I need to have a query so I can fetch just the first row of a group something like this:
Please take in to account that I need the fastest way because the real table is not like that and could have lots of data to be filter that way.
Thanks in advance.
this depends greatly on how you define 'the first in the group'
something like this:
select name, min(code)
from mytable
group by name
order by name
Assuming the table name is test (change to match yours), try this
CREATE TABLE [dbo].[test](
[name] [varchar](3) NULL,
[code] [varchar](5) NULL,
[RowNumber] [int] NOT NULL,
CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED
(
[RowNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A1','AED',1)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A1','BG',2)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A1','WS',3)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A2','CER',4)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A2','HJY',5)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A5','OLP',6)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A6','LOO',7)
INSERT INTO [test] ([name],[code],[RowNumber])VALUES('A6','AED',8)
SELECT a.*
FROM dbo.test a
INNER JOIN(SELECT name,
MIN(rownumber) AS rownumber
FROM dbo.test
GROUP BY name) b
ON a.name = b.name
AND a.rownumber = b.rownumber
ORDER BY a.name
If the RowNumber column is always going to be sequential the put an index on that column.