I am trying to add a temporary column to a target table and use that column in a where clause to insert new data into a parent table via stored procedure that I am using for a one-to-one relationship from parent to target table (see code below). I am getting an error with the alter table add column statement thus resulting in the IMPORT_NUMBER being an invalid identifier. Any help would be much appreciated.
EXECUTE IMMEDIATE
'ALTER TABLE TARGET_TABLE ADD IMPORT_NUMBER NUMBER';
INSERT
INTO
TARGET_TABLE(
existing_col_1,
existing_col_2,
existing_col_3,
IMPORT_NUMBER
)
SELECT
STAGED_TABLE.value1,
STAGED_TABLE.value2,
STAGED_TABLE.value3,
STAGED_TABLE.IMPORT_NUMBER
FROM
STAGED_TABLE
GROUP BY
IMPORT_NUMBER;
UPDATE
PARENT_TABLE
SET
target_table_id =(
SELECT
TARGET_TABLE.id
FROM
TARGET_TABLE
WHERE
TARGET_TABLE.IMPORT_NUMBER = PARENT_TABLE.IMPORT_NUMBER
)
WHERE
PARENT_TABLE.IMPORT_NUMBER IS NOT NULL;
EXECUTE IMMEDIATE 'ALTER TABLE TARGET_TABLE DROP COLUMN IMPORT NUMBER';
If this is a stored procedure, the entire procedure is parsed and validated at the time of create or replace procedure. At the time the procedure is created the column IMPORT_NUMBER does not exist, so the insert and update statements can not be validated.
I would try to find a solution that does not include DDL if possible. Can the column be made a permanent part of the table?
If you must follow this path, the insert and update statements will need to be in strings and passed to execute immediate or DBMS_SQL so that they are parsed and validated at run time, after the column is created.
Is it possible, and if so how, to pass data to a table-valued parameter of a stored function using SQL EXEC?
I know how to pass in data from C#. One of my four stored procs using table-valued parameters is not producing the expected results. I'd like to execute my proc from SQL server management studio for debugging purposes, but I am unable to find the correct syntax for doing so, if such a syntax even exists. I haven't found anything relevant in the docs.
My type table:
CREATE TYPE [MyNameSpace].[MyTypeTable] AS TABLE(
//... all my fields
)
My stored proc:
//... bunch of stuff
ALTER PROCEDURE [MyNameSpace].[MyStoredProc]
#MyTypeTableVar MyTypeTable READONLY
AS
BEGIN
//Do a bunch of stuff
//Want to test the stuff in here
END
I have tried:
IF OBJECT_ID('tempdb.dbo.#MyTempTable') IS NOT NULL DROP TABLE tempdb.dbo.#MyTempTable;
select top 0 *
into #MyTempTable
//existing table with structure that matches the table-valued param
from MyNameSpace.MyTable;
//...Long insert statement assigning test data to #MyTempTable
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #MyTempTable;
which throws:
Operand type clash: nvarchar is incompatible with MyTypeTable
You can't use a temp table - you have to use a table variable:
declare #t [MyNameSpace].[MyTypeTable]
insert into #t (/*columns*/) values
(/* first row */),
(/* second row */)
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #t;
(You can populate it with either INSERT ... VALUES as shown above or INSERT ... SELECT if you have an existing table containing the data you care about)
Here's a working example:
-- Declare a table parameter
DECLARE #registryUpdates AS typ_KeyValuePairStringTable;
-- Insert one row
INSERT INTO #registryUpdates
VALUES ('Hello', 'World');
-- Call Stored Procedure
EXEC prc_UpdateRegistry #registryUpdates
I have a problem with a query to store results from a stored procedure in a temporary table. See below for a simplified version of the query itself:
USE [ADataBaseName]
GO
CREATE TABLE #temp(
SrcUD16 VARCHAR(200))
DECLARE #return_value int
INSERT INTO #temp(
SrcUD16)
EXEC #return_value = [dbo].[AStoredProcedure]
#PartKey = 100,
#Entity_Name = N'SomeEntityName,
#PeriodDesc = N'QA - 2014',
#CategoryKey = 12
SELECT * FROM #temp
GO
The stored procedure creates two other temporary tables to be joined in a Select statement:
SELECT SrcUD16 FROM #temp2 LEFT JOIN #temp3
ON #temp2.MinMaxCIC = #temp3.SrcUD15
Executing the first statement above will give me the following error:
'Invalid column name 'SrcUD16'
However, manually executing the stored procedure does yield the expected results for the field SrcUD16. I can also change the fieldname from SrcUD16 to SrcUD15 which results in a working query albeit incorrect column heading (i.e. ScrUD16 data with 'SrcUD15' as heading).
I strongly suspect this error has something to do with the order in which the temp tables are created and what the query recognizes as allowed field headings. Perhaps someone with better understanding has soem pointers for me?
Thanks in advance
I have created a stored procedure that returns the id of last inserted row of a table based on one condition.
Condition is such that if the row being inserted already exists then it takes identity column of the row otherwise it inserts a new row into the table.
To do this, I have written the following code in a stored procedure
ALTER PROCEDURE [dbo].[Test_Procedure]
#description nvarchar(max)
AS
BEGIN
DECLARE #tempId int;
SELECT CommentId
INTO tempId
FROM TestTable
WHERE description = #description;
IF #tempId IS NULL
BEGIN
INSERT INTO TestTable
VALUES (#description);
SELECT scope_identity();
END
ELSE
BEGIN
SELECT #tempId FROM dual;
END
DROP TABLE tempId;
END
When I run the above stored procedure, first time it ran successfully and then on wards it started throwing the following error message
Msg 2714, Level 16, State 6, Procedure Test_Procedure, Line 15
There is already an object named 'tempId' in the database.
The bit I'm not understanding is tempId is used as a variable not as a table. I have seen people with the similar problem but in their case they used temporary tables
I really appreciate your help in resolving the above issue.
Try this syntax for setting your variable.
SELECT #tempId = CommentId from TestTable where description = #description;
Currently your 'select into' is creating a table 'tempId' on the database.
Note: the highest linked question does not solve the problem for system stored procedures, but it's close. With help of the commenters, I came to a working answer.
Trying to use statements such as the following for sp_spaceused, throws an error
SELECT * INTO #tblOutput exec sp_spaceused 'Account'
SELECT * FROM #tblOutput
The errors:
Must specify table to select from.
and:
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
When I fully declare a table variable, it works as expected, so it seems to me that the stored procedure does return an actual table.
CREATE TABLE #tblOutput (
name NVARCHAR(128) NOT NULL,
rows CHAR(11) NOT NULL,
reserved VARCHAR(18) NOT NULL,
data VARCHAR(18) NOT NULL,
index_size VARCHAR(18) NOT NULL,
unused VARCHAR(18) NOT NULL)
INSERT INTO #tblOutput exec sp_spaceused 'Response'
SELECT * FROM #tblOutput
Why is it not possible to use a temp table or table variable with the result set of EXECUTE sp_xxx? Or: does a more compact expression exist than having to predefine the full table each time?
(incidentally, and off-topic, Googling for the exact term SELECT * INTO #tmp exec sp_spaceused at the time of writing, returned exactly one result)
TL;DR: use SET FMTONLY OFF with OPENQUERY, details below.
It appears that the link provided by Daniel E. is only part of the solution. For instance, if you try:
-- no need to use sp_addlinkedserver
-- must fully specify sp_, because default db is master
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'exec somedb.dbo.sp_spaceused ''Account''')
you will receive the following error:
The OLE DB provider "SQLNCLI10" for linked server "LOCALSERVER\SQL2008" supplied inconsistent metadata for a column. The name was changed at execution time.
I found the solution through this post, and then a blog-post on OPENQUERY, which in turn told me that until SQL2008, you need to use SET FMTONLY OFF. The final solution, which is essentially surprisingly simple (and easier to accomplish since there is no need to specify a loopback linked server), is this:
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'SET FMTONLY OFF
EXEC somedb.dbo.sp_spaceused ''Account''')
In addition, if you haven't set DATA-ACCESS, you may get the following error:
Server 'SERVERNAME\SQL2008' is not configured for DATA ACCESS.
This can be remedied by running the following command:
EXEC sp_serveroption 'SERVERNAME\SQL2008', 'DATA ACCESS', TRUE
We cannot SELECT from a stored procedure thats why SELECT * INTO ..Exec sp_ will not work.
To get the result set returned from a store procedure we can INSERT INTO a table.
SELECT INTO statement creates a table on fly and inserts data from the source table/View/Function. The only condition is source table should exist and you should be able to Select from it.
Sql Server doesn't allow you to use SELECT from sp_ therefore you can only use the INSERT INTO statement when executing a stored procedure this means at run time you can add the returned result set into a table and Select from that table at later stage.
INSERT INTO statement requires the destination table name, An existing table. Therefore whether you use a Temp Table, Table variable or Sql server persistent table you will need to create the table first and only they you can use the syntax
INSERT INTO #TempTable
EXECUTE sp_Proc
Using [YOUR DATABASE NAME]
CREATE TABLE [YOURTABLENAME]
(Database_Name Varchar(128),
DataBase_Size VarChar(128),
unallocated_Space Varchar(128),
reserved Varchar(128),
data Varchar(128),
index_size Varchar(128),
unused Varchar(128)
);
INSERT INTO dbo.[YOUR TABLE NAME]
(
Database_Name,
DataBase_Size,
unallocated_Space,
reserved,
data,
index_size,
unused
)
EXEC sp_spaceused #oneresultset = 1
--To get it to return it all as one data set add the nonresultset=1 at the end and viola good to go for writing to a table. :)