Insert into select Subquery returned more than 1 value - sql

I have the following code and it give me an error when the table #ListaDeProducto has more than 1 row. Any idea?
insert into Solicitud_Plastico_Interna_Detalle(
IDSolicitud_Plastico_Interna
,IDTipo_Producto
,Cantidad_Solicitada
,Create_User
,Create_Date
,Contingencia
,Total
)
select
#IdSolicitud
,IDTipo_Producto
,Cantidad_Requerida
,#USUARIO
,getdate()
,Contingencia
,Total
from #ListaDeProducto
Table schema
CREATE TYPE [ListaProductoTableType2] AS TABLE
(
IDTipo_Producto int,
Tipo_Producto varchar(1000),
Cantidad_Requerida int,
Contingencia int ,
Total int,
IdSolicitud_batch varchar(100)
)
GO

I still will bet there is some trigger in the table.
So why you dont try create a new table to prove this query is ok with multiple rows
CREATE TABLE Solicitud_Plastico_Temporal AS (
select
#IdSolicitud as IDSolicitud_Plastico_Interna
,IDTipo_Producto
,Cantidad_Requerida
,#USUARIO as Create_User
,getdate() as Create_Date
,Contingencia
,Total
from #ListaDeProducto
)

Related

Get SQL Distinct Row Without NULL Values

I'm trying to get a distinct row using SQL from set of records that have matching key/id value, but NULLs in different columns. Hard to explain so please see screenshot. Any ideas?
create temporary table my_table (
id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10)
);
insert into my_table (
id, segmentdate1, converted1, segmentdate2, converted2
)
values
('Michael','9/15/2020','No',NULL,NULL),
('Michael',NULL,NULL,'7/1/2019','Yes')
;
You seem to want aggregation:
select id, max(segmentdate1) as segmentdate1, max(converted1) as converted1,
max(segmentdate2) as segmentdate2, max(converted2) as converted2
from t
group by id;
Note: I made up names for the columns so they are unique.
This is probably a result set created from another query. That query probably has the wrong group by keys. You should probably fix that query.
declare #my_table table (
id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10)
);
insert into #my_table (
id, segmentdate1, converted1, segmentdate2, converted2
)
values
('Michael','9/15/2020','No',NULL,NULL),
('Michael',NULL,NULL,'7/1/2019','Yes')
;
select id,max(isnull(segmentdate1,'1200-01-01')) segmentdate2
,max(isnull(converted1,'')) converted1, max(isnull(segmentdate2,'1200-01-01')) segmentdate2
,max(isnull(converted2,'')) converted2
from #my_table
group by id

SQL IDENTITIY Column not starting with 1

I have a temp table in SQL 2014. In this table variable I have an identity column declared.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY
, IncidentResolvedOn date
, IncidentCreatedOn date
, IncidentClosedOn date
, TaskAssigned date
, TaskCompleted date
, TaskID float
, IncidentTeamID int
, TotalDaysOutstanding int
, TierInfo varchar(15)
, Task_NoTask varchar(15)
, Tier_2_Days_Outstanding int
, Tier_1_Days_Outstanding int
, DaysToResolve int
, BadDays int
, StartDate date
, EndDate date
)
When I run the rest of the query the ID column sometimes doesn't start with 1, instead it starts with some random number. The code below is what I use to insert into this table variable.
INSERT INTO #TempTable(IncidentResolvedOn, IncidentCreatedOn, IncidentClosedOn,TaskAssigned, TaskCompleted, TaskID, IncidentTeamID )
SELECT [Incident Resolved On]
, [Incident Created On]
, [Incident Closed On]
, [Task Assigned On]
, [Task Completed On]
, [Task ID]
, IncidentTeamID
FROM HEATData
This happens in both a table variable and temp table. I've never seen this happen before. Usually when I use the IDENTITY(1,1) phrase it always starts with 1 no matter how many times I create that table. Any suggestions out there?
I imagine your connection is staying open and thus, your identity isn't resetting for your local variable. Here's an example.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
delete from #TempTable
insert into #TempTable
values
(1),(2)
select * from #TempTable
Now, if you'd wrap this in it's own batch using GO you could see this wouldn't happen. In fact, you have to re-declare your table variable.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
go
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
This would be the same for a #TempTable as well if you didn't explicitly drop the #TempTable or the connection remained open. Of course, for actual tables the increment will continue similarly to the first examaple.

Replicating rows in a table by the columns

I need to develop a report I create it in excel but it became so heavy that even my PC cannot open it.
Right now I decide to create it with SQL.
The excel input is something like this:
Service_order PENDING_DAYS SERVICE_TYPE ASC code INOUTWTY Part_code1 Part_code2 Part_code3 Part_code4 Part_code5
4182864919 18 CI 3440690 LP GH82-11218A GH96-09406A GH81-13594A GH02-11552A GH02-11553A
4182868153 18 CI 4285812 LP GH97-17670B
4182929636 17 CI 4276987 LP GH97-17260C GH02-10203A
4182953067 16 CI 3440690 LP GH97-17940C
4182954688 16 CI 6195657 LP GH82-10555A GH97-17852A GH81-13071A
4182955036 16 PS 6195657 LP GH97-17940C
and the result using this codes
=HLOOKUP(Sheet3!A$1;Sheet3!$A$1:$F$10000;CEILING((ROW()-ROW(Sheet3!$A$1))/5+1;1);FALSE)"
=OFFSET(WholePart;TRUNC((ROW()-ROW($G$2))/COLUMNS(WholePart));MOD(ROW()-ROW($G$2);COLUMNS(WholePart));1;1)
* WholePart is partCode values.
are like this:
What I want to do is to convert those formula or have an output just like this.
Appreciate it.
My advice is prepare your data in EXCEL and load into normalized tables. Then you can get the result by joining the tables.
create table T1(
Service_order bigint primary key,
PENDING_DAYS int,
SERVICE_TYPE varchar(10),
ASC_code int,
INOUTWTY varchar(10)
);
create table T2(
Service_order bigint,
Part_code varchar(50)
);
insert into T1(Service_order, PENDING_DAYS, SERVICE_TYPE, ASC_code, INOUTWTY)
values
(4182864919 , 18,'CI',3440690,'LP'),
(4182868153 , 18,'CI',4285812,'LP'),
(4182929636 , 17,'CI',4276987,'LP'),
(4182953067 , 16,'CI',3440690,'LP'),
(4182954688 , 16,'CI',6195657,'LP'),
(4182955036 , 16,'PS',6195657,'LP');
insert into T2(Service_order, Part_code)
values
(4182864919,'GH82-11218A'),
(4182864919,'GH96-09406A'),
(4182864919,'GH81-13594A'),
(4182864919,'GH02-11552A'),
(4182864919,'GH02-11553A'),
(4182868153,'GH97-17670B'),
(4182929636,'GH97-17260C'),
(4182929636,'GH02-10203A'),
(4182953067,'GH97-17940C'),
(4182954688,'GH82-10555A'),
(4182954688,'GH97-17852A'),
(4182954688,'GH81-13071A'),
(4182955036,'GH97-17940C')
select T1.*, T2.Part_code
from T1
join T2 on T1.Service_order = T2.Service_order
order by T1.Service_order, T2.Part_code;
EDIT
Alternatively you can load original EXCEL data (first table) and them normalize it in SQL.
-- create normalized tables
create table T1(
Service_order bigint primary key,
PENDING_DAYS int,
SERVICE_TYPE varchar(10),
ASC_code int,
INOUTWTY varchar(10)
);
create table T2(
Service_order bigint,
Part_code varchar(50)
);
-- load data from excel.
create table excelData(
Service_order bigint,
PENDING_DAYS int,
SERVICE_TYPE varchar(10),
ASC_code int,
INOUTWTY varchar(10),
Part_code1 varchar(50),
Part_code2 varchar(50),
Part_code3 varchar(50),
Part_code4 varchar(50),
Part_code5 varchar(50)
);
-- Below i use sample data insert instead of load.
insert into excelData(Service_order, PENDING_DAYS, SERVICE_TYPE, ASC_code, INOUTWTY
,Part_code1, Part_code2, Part_code3, Part_code4, Part_code5)
values
(4182864919 , 18,'CI',3440690,'LP','GH82-11218A','GH96-09406A','GH81-13594A','GH02-11552A','GH02-11553A'),
(4182868153 , 18,'CI',4285812,'LP','GH97-17670B','','','',''),
(4182929636 , 17,'CI',4276987,'LP','GH97-17260C','GH02-10203A','','',''),
(4182953067 , 16,'CI',3440690,'LP','GH97-17940C','','','',''),
(4182954688 , 16,'CI',6195657,'LP','GH82-10555A','GH97-17852A','GH81-13071A','',''),
(4182955036 , 16,'PS',6195657,'LP','GH97-17940C','','','','');
-- store loaded data into normalized tables.
insert into T1(Service_order, PENDING_DAYS, SERVICE_TYPE, ASC_code, INOUTWTY)
select Service_order, PENDING_DAYS, SERVICE_TYPE, ASC_code, INOUTWTY
from excelData;
insert into T2(Service_order, Part_code)
select Service_order, Part_code
from excelData
cross apply (
--unpivot
select Part_code1 as Part_code where len(Part_code1) > 0
union all
select Part_code2 where len(Part_code2) > 0
union all
select Part_code3 where len(Part_code3) > 0
union all
select Part_code4 where len(Part_code4) > 0
union all
select Part_code5 where len(Part_code5) > 0
) unp;
-- check it
select * from T1;
select * from T2;

Select only few columns from procedure and insert into table

I have a stored procedure that returns 6 columns. But I want to take only 2 columns and insert them into my table variable.
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable EXEC [GetAllTenantCategories] #TenantId
When I run this
Column name or number of supplied values does not match table
definition
How to insert only specified columns from a stored procedure?
I do not want to use SELECT INTO as it is not supported by SQL Azure
Tried below and got Invalid object name '#Temp'
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #Temp EXEC [GetAllTenantCategories] 1
INSERT INTO #CategoryTable (CategoryId, Name)
SELECT CategoryId, Name from #Temp
DROP TABLE #Temp
You can create a temp table first and the INSERT the required columns in your table variable.
CREATE TABLE #temp
(
your columns and datatype
)
INSERT INTO #temp
EXEC [GetAllTenantCategories] #TenantId
Then you can,
DECLARE #CategoryTable TABLE(
CategoryId Int NOT NULL,
Name nvarchar(255) NOT NULL
)
INSERT INTO #CategoryTable (CategoryId, Name)
select CategoryId, Name from #temp
Also drop the #temp table,
DROP TABLE #temp
Refer the points taken from https://www.simple-talk.com/sql/performance/execution-plan-basics/
When the Estimated Plan is Invalid
In some instances, the estimated plan won't work at all. For example, try generating an estimated plan for this simple bit of code:
CREATE TABLE TempTable
(
Id INT IDENTITY (1 , 1 )
,Dsc NVARCHAR (50 )
);
INSERT INTO TempTable ( Dsc )
SELECT [Name]
FROM [Sales] .[Store] ;
SELECT *
FROM TempTable ;
DROP TABLE TempTable ;
You will get this error:
Invalid object name 'TempTable'.
The optimizer, which is what is used to generate Estimated Execution plans, doesn't execute T-SQL.
It does run the stateĀ­ments through the algebrizer , the process outlined earlier that is responsible for verifying the names of database objects. Since the query has not yet been executed, the temporary table does not yet exist. This is the cause of the error.
Running this same bit of code through the Actual execution plan will work perfectly fine.
Hope you got why your temp table approach not worked :) Because you might tried as T-SQL
We can use OPENQUERY
SELECT EmployeeID,CurrentSalary INTO #tempEmp
FROM OPENQUERY(LOCALSERVER,'Exec TestDB.dbo.spEmployee')

insert data into several tables

Let us say I have a table (everything is very much simplified):
create table OriginalData (
ItemName NVARCHAR(255) not null
)
And I would like to insert its data (set based!) into two tables which model inheritance
create table Statements (
Id int IDENTITY NOT NULL,
ProposalDateTime DATETIME null
)
create table Items (
StatementFk INT not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk)
)
Statements is the parent table and Items is the child table. I have no problem doing this with one row which involves the use of IDENT_CURRENT but I have no idea how to do this set based (i.e. enter several rows into both tables).
Thanks.
Best wishes,
Christian
Another possible method that would prevent the use of cursors, which is generally not a best practice for SQL, is listed below... It uses the OUTPUT clause to capture the insert results from the one table to be used in the insert to the second table.
Note this example makes one assumption in the fact that I moved your IDENTITY column to the Items table. I believe that would be acceptable, atleast based on your original table layout, since the primary key of that table is the StatementFK column.
Note this example code was tested via SQL 2005...
IF OBJECT_ID('tempdb..#OriginalData') IS NOT NULL
DROP TABLE #OriginalData
IF OBJECT_ID('tempdb..#Statements') IS NOT NULL
DROP TABLE #Statements
IF OBJECT_ID('tempdb..#Items') IS NOT NULL
DROP TABLE #Items
create table #OriginalData
( ItemName NVARCHAR(255) not null )
create table #Statements
( Id int NOT NULL,
ProposalDateTime DATETIME null )
create table #Items
( StatementFk INT IDENTITY not null,
ItemName NVARCHAR(255) null,
primary key (StatementFk) )
INSERT INTO #OriginalData
( ItemName )
SELECT 'Shirt'
UNION ALL SELECT 'Pants'
UNION ALL SELECT 'Socks'
UNION ALL SELECT 'Shoes'
UNION ALL SELECT 'Hat'
DECLARE #myTableVar table
( StatementFk int,
ItemName nvarchar(255) )
INSERT INTO #Items
( ItemName )
OUTPUT INSERTED.StatementFk, INSERTED.ItemName
INTO #myTableVar
SELECT ItemName
FROM #OriginalData
INSERT INTO #Statements
( ID, ProposalDateTime )
SELECT
StatementFK, getdate()
FROM #myTableVar
You will need to write an ETL process to do this. You may want to look into SSIS.
This also can be done with t-sql and possibly temp tables. You may need to store unique key from OriginalTable in Statements table and then when you are inserting Items - join OriginalTable with Statements on that unique key to get the ID.
I don't think you could do it in one chunk but you could certainly do it with a cursor loop
DECLARE #bla char(10)
DECLARE #ID int
DECLARE c1 CURSOR
FOR
SELECT bla
FROM OriginalData
OPEN c1
FETCH NEXT FROM c1
INTO #bla
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO Statements(ProposalDateTime) VALUES('SomeDate')
SET #ID = SCOPE_IDENTITY()
INSERT INTO Items(StateMentFK,ItemNAme) VALUES(#ID,#bla)
FETCH NEXT FROM c1
INTO #bla
END
CLOSE c1
DEALLOCATE c1