SQL Server stored procedure create table with dynamic number of column - sql-server-2008

I'm new to stored procedure, and trying to figure out how to create a table with a dynamic number of columns.
I'm using Microsoft SQL Server 2008.
I have the following query which is meant to be used to store data passed from a XML source into a table which should be created by this stored procedure.
CREATE PROCEDURE AddClaimData_newV2
#xml_text VARCHAR(4000),
#devYearColumnNumber INT
AS
DECLARE #i INT
DECLARE #tempTable TABLE (
ProductName VARCHAR(50),
Year INT,
Value1 FLOAT ,
Value2 FLOAT ,
Value3 FLOAT ,
Value4 FLOAT )
EXEC sp_xml_preparedocument #i OUTPUT, #xml_text
INSERT INTO #tempTable
SELECT * FROM
OPENXML(#i, '/root/Product/Year/Value1/Value2/Value3/Value4', 1)
WITH
(ProductName VARCHAR(50) '../../../../../#Name',
Year INT '../../../../#Year',
Value1 FLOAT '../../../#Value',
Value2 FLOAT '../../#Value',
Value3 FLOAT '../#Value',
Value4 FLOAT '#Value')
/* create a new table and store all the data from #tempTable */
EXEC sp_xml_removedocument #i
Basically, ProductName and Year are fixed columns, but the Value[i] columns are decided by parameter devYearColumnNumber.
My questions are :
how to use the parameter to dynamically create those Value[i] columns
then, how to create a new table with those columns to store data from #tempTable

declare #currentColumnNumber int, #sqlCommandToCreateTable nvarchar(4000)
set #currentColumnNumber = 1
set #sqlCommandToCreateTable = 'CREATE TABLE testClaimData (
ProductName VARCHAR(50),
Year INT '
while #currentColumnNumber <= #devYearColumnNumber
begin
set #sqlCommandToCreateTable = #sqlCommandToCreateTable + ' ,
Value' + convert(varchar, #currentColumnNumber) + ' FLOAT'
set #currentColumnNumber = #currentColumnNumber + 1
end
set #sqlCommandToCreateTable = #sqlCommandToCreateTable + ' )'
exec sp_executeSql #sqlCommandToCreateTable
--[Test this with:]-- exec sp_executeSql N'select * from testClaimData'
--similar mechanism for the "INSERT INTO" here

Related

Sorting integers in a string with TSQL

I am trying to sort a string such as '3,9,6' to '3,6,9' with TSQL. My approach was extracting the characters from the string, casting them as integers and putting them into a #temptable using a primary key for sorting. For this I created this procedure:
create proc sortstring(#string varchar(50))
as
declare #limit int = len(#string)
declare #counter int = 1
declare #temps char
create table #temptable (tempstring varchar(30) primary key)
while #counter<=#limit
begin
set #temps = SUBSTRING(#string,#counter,1)
if(#temps!=',')
insert into #temptable values (CAST(#temps as int))
set #counter= #counter+1
end
After this process, I was thinking to extract the integers from #temptable with a while loop to create the sorted string format '3,6'9'. But I think my whole approach is not performance efficient.
Any suggestions?
Below method should be a bit better than the while loop
declare #string varchar(255) = '3,9,6,0,5,12,88,15,23,45,77,88,125,1'
declare #TableList table (tmpStr int)
DECLARE #XML XML
SET #XML = '<root><csv>' + replace(#string, ',', '</csv><csv>') + '</csv></root>'
INSERT #TableList
SELECT replace(Word.value('.', 'integer'), CHAR(10), '')
FROM #XML.nodes('/root/csv') AS WordList(Word)
select * from #TableList order by 1
go
IF OBJECT_ID('tempdb.dbo.#TableList') IS NOT NULL
DROP TABLE #TableList
create table #TableList (tmpStr int)
declare #string varchar(255) = '3,9,6,0,5,12,88,15,23,45,77,88,125,1'
SET #string = 'SELECT ' + REPLACE(#string,',',' UNION ALL SELECT ')
SET #string='INSERT INTO #TableList (tmpStr) ' + #string
EXEC( #string)
SELECT * FROM #TableList ORDER BY tmpStr
Its not a conventional approach but it runs fast.

Select UNION from multiple tables via variable

I have a query that selects from multiple tables using a join. I want to execute this query from different databases via a loop.
I have accomplished that via (simplified query):
DECLARE #intCounter int
SET #intCounter = 1
DECLARE #tblBedrijven TABLE (ID int identity(1,1),
CompanyName varchar(20),
DatabaseTable varchar(100))
INSERT INTO #tblBedrijven VALUES ('001-CureCare', '<TABLE/ DATABASE1> AUS'),
('002-Cleaning', '[global_nav5_prod].[dbo].<TABLE/ DATABASE2>] AUS')
DECLARE #strCompany varchar(20)
DECLARE #strTable varchar(100)
WHILE (#intCounter <= (SELECT MAX(ID) FROM #tblBedrijven))
BEGIN
SET #strTable = (SELECT DatabaseTable FROM #tblBedrijven
WHERE ID = #intCounter)
SET #strCompany = (SELECT CompanyName FROM #tblBedrijven
WHERE ID = #intCounter)
EXEC('SELECT ''' + #strCompany + ''' as Company,
AUS.[User],
AUS.[E-mail]
FROM' + #strTable)
SET #intCounter = #intCounter + 1
END
My problem is that the result generates 2 separate tables (for every loop). I want to union the results but have no clue how.
Any suggestions?
Thanks in advance.
Can't you use something like the below code where you append all the sqls with union and finally execute the sql once only without executing in a loop. I am not an expert in SQL Server but I have written many other similar stored procedures using other RDBMS. So please bear any syntax errors.
DECLARE #intCounter int
DECLARE #maxId int
SET #intCounter = 1
DECLARE #tblBedrijven TABLE (ID int identity(1,1),
CompanyName varchar(20),
DatabaseTable varchar(100))
INSERT INTO #tblBedrijven VALUES ('001-CureCare', '<TABLE/ DATABASE1> AUS'),
('002-Cleaning', '[global_nav5_prod].[dbo].<TABLE/ DATABASE2>] AUS')
DECLARE #strCompany varchar(20)
DECLARE #strTable varchar(100)
DECLARE #strSql varchar(5000)
SET #maxId = (SELECT MAX(ID) FROM #tblBedrijven)
WHILE (#intCounter <= #maxId)
BEGIN
SET #strTable = (SELECT DatabaseTable FROM #tblBedrijven
WHERE ID = #intCounter)
SET #strCompany = (SELECT CompanyName FROM #tblBedrijven
WHERE ID = #intCounter)
SET #strSql = #strSql + ('SELECT ''' + #strCompany + ''' as Company,
AUS.[User],
AUS.[E-mail]
FROM' + #strTable)
IF #intCounter < #maxId THEN
BEGIN
SET #strSql = #strSql + ' UNION '
END
SET #intCounter = #intCounter + 1
END
EXEC(#strSql)

When I am trying to drop tables using below script , it seems not working.

I am trying to drop tables from each server. My Server 1 has 3 Databases and Server 2 has 6 and Server 3 has 8.
Below is the SQL Script that I wrote to perform the drop operation from each databases in in particular server. After I perform these operation.
DECLARE
#LoopId int,
#Command varchar(500),
#tblName varchar(100)
DECLARE #List TABLE
(
TableName sysname not null,
LoopId int not null identity(1,1)
)
-- Load with tables you wish to drop
INSERT #List (TableName)
SELECT name FROM [Morgage].sys.objects WHERE type = 'u' and name like '%JKL%'
SELECT name FROM [Scorecard].sys.objects WHERE type = 'u'and name like '%JKL%'
SELECT name FROM [Core].sys.objects WHERE type = 'u' and name like '%JKL%'
SET #LoopId = ##rowcount
-- Go through list and process each item
WHILE #LoopId > 0
BEGIN
SET #tblName = (SELECT TableName from #List where LoopId = #LoopId)
SET #Command = 'Drop table ' + #tblName
execute (#Command)
SET #LoopId = #LoopId - 1
END
Above query result says rows affected but then when i go and try to test is using below query. I do see everything. What my query did actually? Am I doing it right?
SELECT name FROM [Scorecard].sys.objects WHERE type = 'u'and name like '%JKL%'
Any help will be appreciated. Thanks.
Try this version of your script:-
DECLARE
#LoopId int,
#Command varchar(500),
#tblName varchar(100),
#dbName sysname
DECLARE #List TABLE
(
DBName sysname not null,
TableName sysname not null,
LoopId int not null identity(1,1)
)
-- Load with tables you wish to drop
INSERT #List (DBName, TableName)
SELECT 'Morgage',name FROM [Morgage].sys.objects WHERE type = 'u' and name like '%JKL%'
UNION
SELECT 'Scorecard',name FROM [Scorecard].sys.objects WHERE type = 'u'and name like '%JKL%'
UNION
SELECT 'Core',name FROM [Core].sys.objects WHERE type = 'u' and name like '%JKL%'
SET #LoopId = ##rowcount
-- Go through list and process each item
WHILE #LoopId > 0
BEGIN
SELECT #tblName = TableName, #dbName=DBName from #List where LoopId = #LoopId
SET #Command = 'USE ' + #dbName + ';if not exists(select 1 from sys.foreign_keys where parent_object_id=object_id(''' + #tblName + ''',''U'')' + char(10) + 'Drop table ' + #tblName + ';'
execute (#Command)
SET #LoopId = #LoopId - 1
END
Might be the queries are not committing by default. Try specify it explicitly

serialising rows in a table

I have a table which contains header information for transactions. The transactions belong to different projects.
In the header I have columns:
rhguid - uniqueidentifier
rhserial - int
rh_projectID - int
First I insert the row (there's more columns)
Then I calculate the serial number for that project:
update responseheader
set rhSerial = 1 + (select isnull(max(rhSerial), 0)
from responseheader
where (rhstatus = 0) AND (rh_projectID = 1234))
where
(rhGUID = <preassignedGUID>);
However when there are many transactions happening at the same time for a project I am finding duplicate rhserial values.
I'm doing this in classic ASP with SQL Server 2008.
Is there a better way?
From your example, it doesn't look like you're using a transaction. My guess is that the SELECT portion of the statement is running as READ UNCOMMITTED, otherwise you would not see duplicates. There are ways to start transactions with ADO, but I prefer using stored procedures instead.
Try implementing something like this:
CREATE PROC dbo.ResponseHeader_Insert
<more data to insert>,
#ProjectID INT,
#Status SMALLINT
as
insert responseheader (column names here)
select <param values here>, isnull(max(rhSerial), 0) + 1
from responseheader
where (rhstatus = #Status) AND (rh_projectID = #ProjectID))
If this doesn't work for ya, try creating sequence tables (one for each sequence).
create table <tablename> (
SeqID int identity(1,1) primary key,
SeqVal varchar(1)
)
Create a procedure to get the next identity:
create procedure GetNewSeqVal_<tablename>
as
begin
declare #NewSeqValue int
set NOCOUNT ON
insert into <tablename> (SeqVal) values ('a')
set #NewSeqValue = scope_identity()
delete from <tablename> WITH (READPAST)
return #NewSeqValue
end
If there are too many sequence tables that need to be created or you want to create sequences on the fly, try this approach:
Create table AllSequences (
SeqName nvarchar(255) primary key, -- name of the sequence
Seed int not null default(1), -- seed value
Incr int not null default(1), -- incremental
Currval int
)
Go
create procedure usp_CreateNewSeq
#SeqName nvarchar(255),
#seed int = 0,
#incr int = 1
as
begin
declare #currval int
if exists (
select 1 from AllSequences
where SeqName = #SeqName )
begin
print 'Sequence already exists.'
return 1
end
if #seed is null set #seed = 1
if #incr is null set #incr = 1
set #currval = #seed
insert into AllSequences (SeqName, Seed, Incr, CurrVal)
values (#SeqName, #Seed, #Incr, #CurrVal)
end
go
create procedure usp_GetNewSeqVal
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
go

The return types for the following stored procedures could not be detected

While drag-drop a stored procedure in dbml file I get this error:
Unknown Return Type
The return types for the following stored procedures could not be detected. Set the return type for each stored procedure in the Properties window.
How can I resolve this error?
This problem occurs whenever the designer cannot figure out the return type of the SP.
Same problem and solutions described here
How to get multiple result set of procedure using LINQ to SQL
Basically this is the solution from the link:
Avoid using #temp Table in your stored procedure, instead of you can use Table type variable like below (#TempTable)
Ex:
DECLARE #TempTable TABLE
(
AttributeID INT,
Value NVARCHAR(200)
)
INSERT INTO #TempTable Select * from Attribute
OR
--Execute SP and insert results into #TempTable
INSERT INTO #TempTable Exec GetAttribute #Id
You can do all operation which you was doing with #Temp table like
Join, Insert, Select etc.
Add these lines right after parameters declaration
AS
IF 1=0 BEGIN
SET FMTONLY OFF
END
After this, write BEGIN and start your procedure work .
I was using a temp table in my SQL and was getting this error. I converted the temp table to table variables and that resolved my issue.
This can be also the problem of access rights. If the stored procedure doesn't have an access to the table you get the same error. I had a query selecting data from another database I didn't have rights for (in fact the account running the Visual Studio connection didn't have the rights) and I received the same error. After adding proper rights everything went fine.
Trying to execute the stored procedure inside VS2010 (by right clicking in Server Explorer and selecting "Execute") helped me to solve the problem.
I've just added about 300 stored procs to my DBML and experienced many of the problems noted here and elsewhere.
Here is a summary of the causes & solutions for the error "The return types for the following stored procedures could not be detected", based on what I have personally experienced. Note that the problems described below can occur in the SP that you are having the error with, or any other SP that is being called from that SP directly or indirectly.
Concatenating integers with string using a '+' symbol. Use CAST() on the integers, or in SQL2012 or higher use the CONCAT() statement.
Referencing tables in other databases. Apparently a permissions issue. I wasn't able to resolve this one.
Any direct or indirect call to XP_CMDSHELL. I wasn't able to resolve this one.
Any syntax error in direct or indirect calls to other stored procs. Fix the call to the SP.
Temp Tables. Replace the Temp Table with a Table Variable.
SET QUOTED_IDENTIFIER OFF is in use, but the table being edited has a Indexed View on it. *Change the set statement to SET QUOTED_IDENTIFIER ON.*
Reason: Your Stored Procedure will be returning a complex type. that is, multiple results or uses a temp table.
Resolution
It entirely depends on what your Stored Procedure is doing. Useful links
http://odetocode.com/code/365.aspx
http://riteshkk2000.blogspot.com/2010/08/error-unknown-return-type-return-types.html
Just in case anyone else comes across this, I have just experienced it myself.
In my case, I was referencing a table in an insert statement that no longer existed in my schema. A closer inspection of my code revealed I was inserting into a table called "Account" which was now called "tblAccount". Visual Studio threw no errors on saving the sp, but I experienced the same error when trying to add the sp to the dbml file.
Hopefully this will help someone else out.
I also had this problem - had to comment out code that was constructing a polygon:
declare
#MapBounds geography
;
select
#MapBounds = geography::STGeomFromText('POLYGON((' +
cast(#NorthEastLng as varchar) + ' ' + cast(#NorthEastLat as varchar) + ', ' +
cast(#SouthWestLng as varchar) + ' ' + cast(#NorthEastLat as varchar) + ', ' +
cast(#SouthWestLng as varchar) + ' ' + cast(#SouthWestLat as varchar) + ', ' +
cast(#NorthEastLng as varchar) + ' ' + cast(#SouthWestLat as varchar) + ', ' +
cast(#NorthEastLng as varchar) + ' ' + cast(#NorthEastLat as varchar) +
'))', 4326)
;
Once it was added to the dmbl, I un-commented out the code and it worked like a champ!
I also had the problem (VS 2012, SQL Server 2008R2). In my case it was a combination of the + operator and various CAST statements in the code. I haven't found a way to replace them with something VisualStudio likes, but I have come up with a workaround:
Workaround "Dummy SELECT":
Create a dummy SELECT statement with all the fields you need to return. For example:
select 'bla bla' as field1, 123123 as field2, 'asñfs' as field3
Comment out your SP code and just leave the dummy SELECT in your SP.
Add your SP in the O/R designer and save (it should do know without an error message)
Restore your original SP (leave the dummy SELECT as a comment for future use)
You might as well consider using CONCAT() method instead of '+' to concat a string. Since I wasn't using temp table and yet still encounter this problem. I found out that concating strings using '+' triggering this.
In my case, I was using this:
SET #errorMessage = CONCAT('Update (ID=', #pnID, ') failed. Name already exists.');
Instead of:
SET #errorMessage = 'Update (ID=' + #pnID + ') failed. Name already exists.';
Just ran into this issue while trying to add a stored procedure into a DBML (LINQ) file.
Doing some research I found that this usually happens when the stored procedure returns multiple results or uses a #temp table for it's final select.
The solution that worked for me was to create a new stored procedure that wrapped the results of the original stored procedure result, into a table variable with the same columns as the temp table.
My wrapper stored proc looked something like this:
DECLARE #NewPrograms TABLE (
Campaign_Number int,
Campaign_Display nvarchar(255)
)
INSERT INTO #NewPrograms
EXEC [dbo].[Original_Stored_Proc_With_Temp_Table_Result] #Program_ID
Select *
From #NewPrograms
Open up your DBML file, drag-and-drop in your new wrapper stored proc.
Make sure the stored procedure runs without erroring. Just had this problem and I assumed the person who made the stored procedure had tested it and did not try it myself.
The solution I found ... I put a SELECT on top (IF) with conditions that are not correct and create a variable table with the result he wanted to exit and then "ELSE" put things right. The first part is only if you understand the process output I want. Look at my example
ALTER PROCEDURE [dbo].[SS_getSearchedProductsDetailsNew]
(
#mk int,
#md int,
#yr int = 0,
#caroption int = 0,
#condition int = 0,
#producttype int = 0 ,
#option int = 0,
#coloroption int = 0
)
AS
declare #sql nvarchar(max)
Begin
if #mk = 0 and #md = 0 and #yr = 0
begin
Declare #TempTable2 TABLE(
ProductID numeric(10),
TypeName nvarchar(50),
MakeID numeric(10),
ModelID numeric(10),
ConditionID numeric(10),
CarOptionsID numeric(10),
OptionsID numeric(10),
ColorOptionsID numeric(10),
Make nvarchar(50),
Model nvarchar(50),
YearID numeric(5),
Color nvarchar(50),
ProductType nvarchar(50),
CarOptionName nvarchar(50),
OptionName nvarchar(50),
ColorOptionName nvarchar(50),
ConditionName nvarchar(50),
Notes nvarchar(500),
Price money,
cog money)
select * from #TempTable2
end
else
begin
select #sql = '
declare #theNotes nvarchar(500)
declare #theMake numeric(10), #theModel numeric(10), #theYear numeric(10)
declare #makeName nvarchar(50), #modelName nvarchar(50), #ID numeric(5)
declare #theProductType nvarchar(50), #theTypeName nvarchar(50)
declare #theColor nvarchar(50),#theProductID numeric(10)
declare #theCondition numeric(10),#theCarOption numeric(10) , #theOption numeric(10), #theColorOption numeric(10)
declare #theConditionName nvarchar(50),#theCarOptionName nvarchar(50), #theOptionName nvarchar(50),#theColorOptionName nvarchar(50)
declare #thePrice money, #theCog money
declare #HoldingTable table(
ID numeric identity,
ProductID numeric(10),
MakeID numeric(10),
ModelID numeric(10),
ConditionID numeric(10),
CarOptionsID numeric(10),
OptionsID numeric(10),
ColorOptionsID numeric(10),
Make nvarchar(50),
Model nvarchar(50),
YearID numeric(5),
Color nvarchar(50),
ProductType nvarchar(50),
Notes nvarchar(500),
Price money,
cog money);
INSERT INTO #HoldingTable (ProductID,MakeID, ModelID , ConditionID, CarOptionsID,OptionsID,ColorOptionsID, Make ,Model,YearID,Color, ProductType, Notes, Price, cog)
SELECT
ProductNumber as ProductID,
tblProductsForSale.MakeID as MakeID,
tblProductsForSale.ModelID as ModelID ,
ConditionID,
CarOptionsID,
OptionsID,
ColorOptionsID,
tblVehicleMake.Make as Make ,
tblVehicleModel.Model as Model,
YearID,
Color,
ProductType, Notes,
tblProductsForSale.ResalePrice as Price,
tblProductsForSale.SellPrice as cog
from tblProductsForSale, tblVehicleMake, tblVehicleModel where
tblProductsForSale.MakeID = tblVehicleMake.MakeID and
tblProductsForSale.ModelID = tblVehicleModel.ModelID
and tblProductsForSale.ProductStatus=''available'' and tblProductsForSale.Custom=0'
if(#mk > 0)
begin
select #sql = #sql + ' and tblProductsForSale.MakeID = ' + convert(varchar, #mk)
end
if #md > 0
Begin
select #sql = #sql + ' and tblProductsForSale.ModelID = ' + convert(varchar, #md)
End
if #yr > 0
begin
select #sql = #sql + ' and tblProductsForSale.YearID = ' + convert(varchar, #yr)
end
if #caroption > 0
begin
select #sql = #sql + ' and tblProductsForSale.CarOptionsID = ' + convert(varchar, #caroption)
end
if #producttype > 0
begin
select #sql = #sql + ' and tblProductsForSale.ProductType = ''' + convert(varchar,#producttype) + ''''
end
if #option > 0
begin
select #sql = #sql + ' and tblProductsForSale.OptionsID = ' + convert(varchar, #option)
end
if #coloroption > 0
begin
select #sql = #sql + ' and tblProductsForSale.ColorOptionsID = ' + convert(varchar, #coloroption)
end
--select #sqlInsert = 'INSERT INTO #HoldingTable (ProductID,MakeID, ModelID , ConditionID, CarOptionsID,OptionsID,ColorOptionsID, Make ,Model,YearID,Color, ProductType, Price, cog) '
--select #sqlExec = #sqlInsert + #sql
--select * from #HoldingTable
select #sql = #sql + 'Declare #TempTable2 TABLE(
ProductID numeric(10),
TypeName nvarchar(50),
MakeID numeric(10),
ModelID numeric(10),
ConditionID numeric(10),
CarOptionsID numeric(10),
OptionsID numeric(10),
ColorOptionsID numeric(10),
Make nvarchar(50),
Model nvarchar(50),
YearID numeric(5),
Color nvarchar(50),
ProductType nvarchar(50),
CarOptionName nvarchar(50),
OptionName nvarchar(50),
ColorOptionName nvarchar(50),
ConditionName nvarchar(50),
Notes nvarchar(500),
Price money,
cog money)
WHILE Exists(Select * from #HoldingTable )
begin
Select #ID = ID FROM #HoldingTable
Select #theProductId = ProductID from #HoldingTable
Select #theMake = MakeID from #HoldingTable
Select #theModel = ModelID from #HoldingTable
Select #theCondition = ConditionID from #HoldingTable
Select #theCarOption = CarOptionsID from #HoldingTable
Select #theOption = OptionsID from #HoldingTable
Select #theColorOption = ColorOptionsID from #HoldingTable
Select #theYear = YearID from #HoldingTable
Select #theColor = Color from #HoldingTable
Select #theProductType = ProductType from #HoldingTable
Select #theTypeName = TypeName from tblProductType WHere ProductTypeID = cast (#theProductType as numeric(10))
Select #thePrice = Price from #HoldingTable
Select #theCog = cog from #HoldingTable
Select #theConditionName = ConditionName from tblConditions Where ConditionID = #theCondition
Select #makeName = Make from tblVehicleMake Where MakeID = #theMake
Select #modelName = Model from tblVehicleModel Where ModelID = #theModel
Select #theCarOptionName = CarOptionsName from tblCarOptions Where CarOptionsID = #theCarOption
Select #theOptionName = OptionsName from tblOptions Where OptionsID = #theOption
Select #theColorOptionName = ColorOptionsName from tblColorOptions Where ColorOptionsID = #theColorOption
Select #theNotes = Notes from #HoldingTable
Select #theProductType = ProductType from #HoldingTable
INSERT INTO #TempTable2 (ProductID,TypeName,MakeID,ModelID,ConditionID ,CarOptionsID,OptionsID ,ColorOptionsID ,Make , Model , YearID ,Color, ProductType, CarOptionName ,OptionName,ColorOptionName ,ConditionName, Notes, Price, cog)
VALUES (#theProductId,#theTypeName, #theMake, #theModel, #theCondition, #theCarOption,#theOption,#theColorOption, #makeName,#modelName, #theYear, #theColor,#theProductType, #theCarOptionName, #theOptionName, #theColorOptionName, #theConditionName, #theNotes, #thePrice , #theCog )
DELETE FROM #HoldingTable Where ID = #ID
end
Select * from #TempTable2 order by ProductID '
end
exec ( #sql )
End
I've struggled a lot on this and came to conclusion, that if your stored procedure is dynamic and is combined with strings you sometimes miss something.. so while importing Visual Studio DBML import/update can not execute/test the procedure, so return type stays undefined, once you correct the procedure (query strings that you are building up to execute) you can add the procedure without any problems.
I had this error too and finally I found out that I have changed a table field name and in procedure it did not change it yet, and so it showed an error when adding to dbml.
Now you can check this on your procedure and your table that fields are the same.
I hope this experience is useful.
A simple way to solve this issue is (December 2019)
1 Just making double # precede #tmp => ##tmp
2 Comment out DROP TABLE #tmp => --DROP TABLE #tmp
Execute stored procedure and make sure that data showed up
Drag stored procedure again and that's it, It will generate return type
Last, Turn your store back to first situation and then save.
Hope I can help.
I got the same error when I dragged and dropped the stored procedure, so I just followed what the error said:
Unknown Return Type
The return types for the following stored procedures could not be detected. Set the return type for each stored procedure in the Properties window.
I selected the stored procedure and then selected properties tab, there there is a option called ReturnType which was empty and then hit the dropdown button on it and selected the table the SP was created and the issue is resolved.
If this doesn't help you can try any of the above answers.
The issue for me was that I had OPTION (RECOMPILE) set to get round a parameter sniffing issue. I temporary removed this while adding the SP and all worked fine.
You must place the
SET NOCOUNT ON;
SET FMTONLY OFF
at the top of the procedure . Like for example:
ALTER PROCEDURE [dbo].[usp_Name]
#your_params
AS
BEGIN
SET NOCOUNT ON;
SET FMTONLY OFF
-- your other codes
End