Showing "Invalid object name " in sqlServer? - sql-server

While Executing the Following query it showing the Invalid object name '#temp1'. can any body knows the error occurred due to which reason this is my orginal code i used to fetch code , her differnt tables are formed i need to get the sum of the each row of each table
DECLARE #t TABLE (
id int IDENTITY(1,1),
BranchName nvarchar(max)
)
DECLARE #n int = 0,
#i int = 1,
#BranchName nvarchar(max),
#sql nvarchar(max),
#columns nvarchar(max)
INSERT INTO #t
SELECT DISTINCT BranchName
FROM ALX_Branches
SELECT #n = ##ROWCOUNT
WHILE #n >= #i
BEGIN
SELECT #BranchName = BranchName
FROM #t
WHERE id = #i
SELECT #columns = (
SELECT DISTINCT ','+QUOTENAME([SubInventory])
FROM #MyTempTable
WHERE [BranchName] = #BranchName
FOR XML PATH('')
)
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt'
EXEC sp_executesql #sql
select * from #temp1

Firstly, there is no need for creating #temp1 table before.
because you are using "Select * into" that already create table within it.
Suppose type this note as a comment, but I don't have enough reputation score.
The reason of
Invalid object name '#temp1'
is: the variable #sql is NULL because #temp1 is not created yet via "Select * into" clause.
so append selecting from #temp1 within dynamic sql as the following:
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt
select * from #temp1 '
EXEC sp_executesql #sql

Related

How can I dynamically convert row to columns and have different column name for each column

How can I convert rows into columns and create different name for each column?
create table #TempTable (InvoiceNum int,State varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL
)
I need something like that:
UPDATE:
Using example I was able to unpivot it but the result is not what I wanted to:
create table #TempTable (InvoiceNum int,State varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL)
--select * from #TempTable
Declare #SQL nvarchar(max),
#query nvarchar(max)
select #SQL = STUFF((SELECT ',' + QUOTENAME(ChargeName)
from #TempTable
group by ChargeName, InvoiceNum
order by InvoiceNum
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
--select #SQL
set #SQL = 'SELECT ' + #SQL + ' from
(
select PercentageRate, ChargeName
from #TempTable
) x
pivot
(
max(PercentageRate)
for ChargeName in (' + #SQL + ')
) p '
exec sp_executesql #SQL;
UPDATE:
Running below query gives me this:
Why ChargeName is not on the first row? I would expect to see it like this: What am I missing?
declare #TempTable table (InvoiceNum int,StateID varchar(2), ChargeName varchar(50), PercentageRate decimal(5,3), FlatRate decimal(5,2))
insert into #TempTable values (235736, 'AZ','Inspection & Policy Fee', NULL,250.00)
,(235736, 'AZ','Surplus Line Tax',0.03,NULL)
,(235736, 'AZ','Stamping Fee',0.002,NULL)
select
InvoiceNum,
ChargeName,
StateID,
PercentageRate,
FlatRate,
row_number() over (partition by InvoiceNum order by ChargeName) as RN
into #TempTable
from #TempTable #TempTable
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(RN)
FROM (SELECT DISTINCT RN FROM #TempTable) AS RN
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT InvoiceNum, ' + #ColumnName + '
FROM #TempTable
PIVOT(MAX(ChargeName)
FOR RN IN (' + #ColumnName + ')) AS PVTTable'
EXEC sp_executesql #DynamicPivotQuery
drop table #TempTable
I would just join the temp table multiple times as needed.
Given your #TempTable
SELECT T1.InvoiceNum,
Tax1_Jurisdiction = T1.State, Tax1_TaxType = T1.ChargeName, Tax1_Percent = T1.PercentageRate, Tax1_FixedRate = T1.FlatRate,
Tax2_Jurisdiction = T2.State, Tax2_TaxType = T2.ChargeName, Tax2_Percent = T2.PercentageRate, Tax2_FixedRate = T2.FlatRate,
Tax3_Jurisdiction = T3.State, Tax3_TaxType = T3.ChargeName, Tax3_Percent = T3.PercentageRate, Tax3_FixedRate = T3.FlatRate
FROM #TempTable T1
JOIN #TempTable T2 ON T1.InvoiceNum = T2.InvoiceNum
JOIN #TempTable T3 ON T1.InvoiceNum = T3.InvoiceNum
WHERE T1.ChargeName = 'Inspection & Policy Fee'
AND T2.ChargeName = 'Surplus Line Tax'
AND T3.ChargeName = 'Stamping Fee'
;

Convert stored procedure which uses exec to populate table to scalar-valued function

I have this stored procedure:
ALTER procedure [dbo].[sp_checker2]
(#Item varchar(70), #location varchar(8))
as
declare #Query varchar(2000)
set #location = 'XXX909'
declare #Table Table (Qty int)
set #Query = 'select TOP 1 * from openquery(xxxx,''SELECT NVL(b.t$st,0) from server.XXXXXID0001 a left join
server.XXXXXID0002 b on a.t$item = b.t$item where b.t$cloc = '''''+ #location + ''''' and trim(a.t$item)='''''+ #Item + ''''''')'
insert into #Table exec (#Query)
if not exists (select * from #Table )
begin
set #Query = 'select TOP 1 * from openquery(xxxx,''SELECT NVL(b.t$st,0) from server.XXXXXID0001 a
left join server.XXXXXID0002 b on a.t$item = b.t$item where trim(a.t$item) = '''''+ #Item + ''''''' )'
insert into #Table exec (#Query)
end
select * from #Table
The thing is I am looking to a query SELECT like this:
SELECT
column1, column2, column3, column4,
(EXEC [dbo].[sp_checker2] 'param1=value of column3', 'param2=another value') AS column5
FROM
table
WHERE
column1 = 'data1'
AND column2 = 'data2'
ORDER BY
column3
I know it is not possible to execute a stored procedure in a SELECT statement in SQL Server and the alternative I have is to convert the stored procedure to a function, but inside the stored procedure I have an exec to insert data into the table variable. Is there a way I can convert this stored procedure to a function ?
P.S. I only save one row in the variable table, ie: if item exists it saves its inventory: "6500"
It is difficult. In a function it is not possible to execute dynamic SQL. I think it is only possible if the WHERE criteria are shifted. You'll be better able to evaluate what impact this has on the performance.
CREATE FUNCTION [dbo].[f_checker2] (#item varchar(70),
#location varchar(8))
RETURNS #result TABLE (
Qty int
)
AS
BEGIN
INSERT
INTO #result
select TOP(1) qty
from openquery(xxxx, 'SELECT NVL(b.t$st,0) AS qty,
b.t$cloc AS location,
trim(a.t$item) AS item
from server.XXXXXID0001 a
left join server.XXXXXID0002 b
on a.t$item = b.t$item')
where location = #location
and item = #item
if not exists (select * from #result)
INSERT
INTO #result
select TOP(1) qty
from openquery(xxxx, 'SELECT NVL(b.t$st,0) AS qty,
b.t$cloc AS location,
trim(a.t$item) AS item
from server.XXXXXID0001 a
left join server.XXXXXID0002 b
on a.t$item = b.t$item')
where item = #item
RETURN
END
GO

Drop multiple columns using subquery within alter table

I need to drop all but few columns from a table while I don't know number and names of these columns in advance. I want to get column names from sys.columns and then drop all columns except few. I need something like this:
alter table Table
drop column (
select a.name as ColumnName
from sys.all_columns a
INNER JOIN sys.tables b
on a.object_id = b.object_id
where b.name = 'Table'
where a.name NOT IN (
RowID,
RemoteUserId,
Email,
FirstName,
)
)
First You need to Create a Function to Split the Comma Separated Strings to Rows
CREATE FUNCTION [dbo].[FnSplit]
(
#List nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Value nvarchar(100)
)
AS
BEGIN
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
GO
Then Create Below Stored Procedure
Create Procedure DropColumnExceptGivn
#table varchar(50),
#Column Varchar(max)
AS
BEGIN
SET NOCOUNT ON;
declare #variables AS TABLE (cols varchar(max))
declare #sql varchar(max) = ''
declare #sql1 varchar(max) = ''
declare #cols nvarchar(max) =''
set #sql1 = 'SELECT Stuff((select '',''+ Column_name '+'from INFORMATION_SCHEMA.COLUMNS where
table_name = ' +''''+#table+''''+
' and column_name not in (SELECT Value FROM dbo.FnSplit('+''''+#column+''''+','',''))
for xml path('''')),1,1,'''')'
print #sql1
insert into #variables
exec (#sql1)
select #cols = cols from #variables
select #cols
set #sql= 'alter table '+ #table + ' drop column ' + #cols
print #sql
exec (#sql)
end
go
--Creating a Sample Table
Create table pets1 (petid int, PetTypeID int, PetName Varchar(20),OwnerId int)
go
Then Execute the below Stored Procedure.
The Parameters are : 1. Table Name 2. The Columns need to be Left (Comma Seperated values)
exec DropColumnExceptGivn 'pets1','PetID, PetTypeID'
go
select *from pets1
Hope This will helps

Create table on SQL Server from dynamic pivot results

Is there a way to directly store the results of a dynamic pivot query into a fixed table? As the result is dynamic I can't create the table by specifying the columnnames and methods like "create table MyTable as (pivot select statement)" seem to fail on SQL server ("Incorrect syntax near the keyword 'AS'").
I have tried to format the SQL below to get a SELECT - INTO - FROM structure but failed to do so. Any help is obviously greatly appreciated!
The SQL used for the pivot is (build thanks to this great website!):
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
Unless I am not following what you are trying to do you should be able to add the INTO mynewTable to your sql that you are going to execute and you should get the new table.
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * INTO mynewTable FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
I just test creating a new table in the following script and it gives me a new table that is in the DB for use:
create table t
(
[month] int,
[id] nvarchar(20),
[cnt] int
)
insert t values (4,'TOTAL',214)
insert t values (5,'TOTAL',23)
insert t values (6,'TOTAL',23)
insert t values (4,'FUNC',47)
insert t values (5,'FUNC',5)
insert t values (6,'FUNC',5)
insert t values (4,'INDIL',167)
insert t values (5,'INDIL',18)
insert t values (6,'INDIL',18)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(month)
FROM t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT *
INTO tabletest from
(
select month, id, cnt
from t
) x
pivot
(
sum(cnt)
for month in (' + #cols + ')
) p '
execute(#query)
drop table t

How to copy a row with every column except identity column (SQL Server 2005)

My code:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid --get data, put into a temp table
ALTER TABLE #t
DROP COLUMN CID -- remove primary key column CID
INSERT INTO CTABLE SELECT * FROM #t -- insert record to table
DROP TABLE #t -- drop temp table
The error is:
Msg 8101,
An explicit value for the identity column in table 'CTABLE' can only
be specified when a column list is used and IDENTITY_INSERT is ON.
And I did set
SET IDENTITY_INSERT CTABLE OFF
GO
DECLARE
#cid INT,
#o INT,
#t NVARCHAR(255),
#c NVARCHAR(MAX),
#sql NVARCHAR(MAX);
SELECT
#cid = 10,
#t = N'dbo.CTABLE',
#o = OBJECT_ID(#t);
SELECT #c = STRING_AGG(QUOTENAME(name), ',')
FROM sys.columns
WHERE [object_id] = #o
AND is_identity = 0;
SET #sql = 'SELECT ' + #c + ' INTO #t
FROM ' + #t + ' WHERE CID = #cid;
INSERT ' + #t + '('+ #c + ')
SELECT ' + #c + ' FROM #t;'
PRINT #sql;
-- exec sp_executeSQL #sql,
-- N'#cid int',
-- #cid = #cid;
However it seems much easier to just build the following SQL and avoid the #temp table altogether:
SET #sql = 'INSERT ' + #t + '(' + #c + ')
SELECT ' + #c + ' FROM ' + #t + '
WHERE CID = #cid;';
PRINT #sql;
-- exec sp_executeSQL #sql,
-- N'#cid int',
-- #cid = #cid;
Try this:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid
ALTER TABLE #t
DROP COLUMN CID
INSERT CTABLE --Notice that INTO is removed here.
SELECT top(1) * FROM #t
DROP TABLE #t
Test Script(Tested in SQL 2005):
CREATE TABLE #TestIDNT
(
ID INT IDENTITY(1,1) PRIMARY KEY,
TITLE VARCHAR(20)
)
INSERT #TestIDNT
SELECT 'Cybenate'
Try specifying the columns:
INSERT INTO CTABLE
(col2, col3, col4)
SELECT col2, col3, col4
FROM #t
Seems like it might be thinking you are trying to insert into the PK field since you are not explicitly defining the columns to insert into. If Identity insert is off and you specify the non-pk columns then you shouldn't get that error.
Here's an example to dynamically build a list of columns - excluding the primary key columns - and execute the INSERT
declare #tablename nvarchar(100), #column nvarchar(100), #cid int, #sql nvarchar(max)
set #tablename = N'ctable'
set #cid = 1
set #sql = N''
declare example cursor for
select column_name
from information_schema.columns
where table_name = #tablename
and column_name not in (
select column_name
from information_schema.key_column_usage
where constraint_name in (select constraint_name from information_schema.table_constraints)
and table_name = #tablename
)
open example
fetch next from example into #column
while ##fetch_status = 0
begin
set #sql = #sql + N'[' + #column + N'],'
fetch next from example into #column
end
set #sql = substring(#sql, 1, len(#sql)-1)
close example
deallocate example
set #sql = N'insert into ' + #tablename + '(' + #sql + N') select top(1) ' + #sql + ' from #t'
--select #sql
exec sp_executesql #sql
If using SQL Server Management Studio and your problems you have too many fields to type them all out except the identity column, then right click on the table and click "Script table as" / "Select To" / "New Query Window".
This will provide a list of fields that you can copy & paste into your own query and then just remove the identity column.
Try invoking the INSERT statement with EXEC:
SELECT * INTO #t FROM CTABLE WHERE CID = #cid
ALTER TABLE #t
DROP COLUMN CID
EXEC('INSERT INTO CTABLE SELECT top(1) * FROM #t')
DROP TABLE #t
You can't do this:
INSERT INTO CTABLE SELECT top(1) * FROM #t
Because the column listings aren't the same. You've dropped the PK column from #t, so you have 1 less column in #t than in CTABLE. This is the equivalent of the following:
INSERT INTO CTABLE(pk, col1, col2, col3, ...)
select top(1) col1, col2, col3, ...
from #t
This wouldn't work for obvious reasons. Similarly, you aren't going to be able to specify the * wildcard to do the insert if you're not inserting all of the columns. The only way to do the insert without including the PK is to specify every column. You can generate a list of columns through dynamic sql, but you'll have to specify them one way or another.

Resources