SQL server stored procedure return a table
A procedure can't return a table as such. However you can select from a table in a procedure and direct it into a table (or table variable) like this:
create procedure p_x
as
begin
declare @t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert @t values('a', 1,1,1)
insert @t values('b', 2,2,2)
select * from @t
end
go
declare @t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert @t
exec p_x
select * from @t
Can a stored procedure/function return a table?
As for now, this is not possible.
Here is the documentation on what may be used in the FROM
clause:
table_references:
table_reference [, table_reference] ...
table_reference:
table_factor
| join_table
table_factor:
tbl_name [[AS] alias] [index_hint)]
| table_subquery [AS] alias
| ( table_references )
| { OJ table_reference LEFT OUTER JOIN table_reference
ON conditional_expr }
join_table:
table_reference [INNER | CROSS] JOIN table_factor [join_condition]
| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON conditional_expr
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor
join_condition:
ON conditional_expr
| USING (column_list)
index_hint:
USE {INDEX|KEY} [FOR JOIN] (index_list)
| IGNORE {INDEX|KEY} [FOR JOIN] (index_list)
| FORCE {INDEX|KEY} [FOR JOIN] (index_list)
index_list:
index_name [, index_name] ...
As you can see, stored procedures are not in this list.
Return table from stored procedure / function after doing merge function SQL Server
A stored procedure can certainly return a result set, which the client can consume directly just like a regular SELECT
statement.
That said, there are a range of options, none of which are perfect. Each suits a different scenario, and are described at length by Erland Sommarskog in How to Share Data between Stored Procedures:
- Table-valued Functions
- Inline Functions
- Multi-statement Functions
- Using a Table
- Sharing a Temp Table
- Process-keyed Table
INSERT-EXEC
- Using SQLCLR
OPENQUERY
- XML
- Cursor Variables
For example, you may not wish to use a permanent table, but a temporary table created by the client and populated by the stored procedure can work well, if directly consuming the results of a SELECT
inside the procedure is not suitable.
How to return a user defined table type from a stored procedure
You just CANNOT return table-valued variable from stored procedure.
As you said, you cannot use table-valued parameter if it's not declared as readonly
.
In your simple case you can use an inline table-valued function instead:
create function getCarDetails( @carNumber varchar(20))
returns table
as
return
select CarNumber, Model
from dbo.cars
where CarNumber = @carNumber;
Can I call a stored procedure in jdbc which returns a table using mysql?
Yes. It's possible to call a MySQL stored procedure to return a resultset using JDBC.
Examples provided here:
https://docs.oracle.com/javase/tutorial/jdbc/basics/storedprocedures.html#calling_javadb_mysql
Pass a table and return a table to a stored procedure or function?
Since your code just does calculations on data (i.e. no side-effects or updates of tables) and isn't coupled to tables, what you can do is to can create a table valued function to do these calculations - the function can take in the table of inputs (R_MODS
)as a table type and also return a table of outputs (Sen
etc).
Here's a SqlFiddle example.
In detail:
You'll need to create a table type for the inputs, e.g.
CREATE TYPE R_MODS_TYPE AS TABLE(
SUBJECTID varchar(max),
ResultCall varchar(max)
);
And define the function as such:
CREATE FUNCTION dbo.DoCalcs(@TheRMods R_MODS_TYPE READONLY)
RETURNS @Result TABLE
(
[SEN] DECIMAL(10,4),
[SenL] DECIMAL(10,4),
[SenU] DECIMAL(10,4),
[1-SPE] DECIMAL(10,4),
[1-SPEL] DECIMAL(10,4),
[1-SpeU] DECIMAL(10,4)
)
AS
BEGIN
DECLARE @TP float, @TN float, @FP float, @FN float, @SEN float, @SPE float,
@M1 float, @M2 float, @Sen95 float, @SpeL float , @SpeU float,
@SenU float, @SenL float;
SET @TP = (SELECT COUNT(SUBJECTID) FROM @TheRMods WHERE ResultCall='TP')
SET @TN = (SELECT COUNT(SUBJECTID) FROM @TheRMods WHERE ResultCall='TN')
SET @FP = (SELECT COUNT(SUBJECTID) FROM @TheRMods WHERE ResultCall='FP')
SET @FN = (SELECT COUNT(SUBJECTID) FROM @TheRMods WHERE ResultCall='FN')
SET @SEN = @TP/(@TP + @FN)
SET @M1 = @TP + @FN
SET @SPE = @TN/(@TN + @FP)
SET @M2 = @FP + @TN
SET @SenL = ( 2*@M1*@SEN + POWER(1.96,2) - 1 - 1.96 * SQRT(POWER(1.96,2)
- 2 -(1/@M1)+ 4*@SEN *(@M1*(1-@SEN) + 1)))/(2*(@M1+POWER(1.96,2)))
SET @SenU = ( 2*@M1*@SEN + POWER(1.96,2) + 1 + 1.96 * SQRT(POWER(1.96,2)
+ 2 -(1/@M1)+ 4*@SEN *(@M1*(1-@SEN) - 1)))/(2*(@M1+POWER(1.96,2)))
SET @SpeL = ( 2*@M2*@SPE + POWER(1.96,2) - 1 - 1.96 * SQRT(POWER(1.96,2)
- 2 -(1/@M2)+ 4*@SPE *(@M2*(1-@SPE) + 1)))/(2*(@M2+POWER(1.96,2)))
SET @SpeU = ( 2*@M2*@SPE + POWER(1.96,2) + 1 + 1.96 * SQRT(POWER(1.96,2)
+ 2 -(1/@M2)+ 4*@SPE *(@M2*(1-@SPE) - 1)))/(2*(@M2+POWER(1.96,2)))
INSERT INTO @Result ([SEN], [SenL], [SenU], [1-SPE], [1-SPEL], [1-SpeU])
SELECT @SEN, @SenL, @SenU, 1-@SPE, 1-@SPEL, 1-@SpeU;
RETURN;
END
You then invoke the table function by declaring an instance of the table type, populating it, and passing it to your function:
DECLARE @TestData R_MODS_TYPE;
INSERT INTO @TestData VALUES ('11-0001','TP'),
('11-0002','TP'),
('11-0003','TP'),
('11-0004','TP'),
... etc.
SELECT * FROM dbo.DoCalcs(@TestData);
Result:
SEN SenL SenU 1-SPE 1-SPEL 1-SpeU
--------- -------- ------- ------- ------- -------
1.0000 0.7166 0.9929 0.5000 0.9081 0.0919
Returning a table in firebird 3.0 with stored function or stored procedure
What you are looking for is a selectable stored procedure. Firebird requires you to explicitly declare the columns the stored procedure returns, so something like returns table
is not an option. For example:
create procedure sp_test_procedure (x integer)
returns (column1 integer, column2 varchar(50))
as
begin
for select value1, value2
from table_name SD
where exists (
SELECT DISTINCT S.PARENT_ID
FROM table_name AS S
WHERE S.COMPONENT_ID = 10011
AND S.CARRIER_GROUP_ID = :X
AND SD.SD_ID = S.PARENT_ID)
into column1, column2
do
begin
suspend;
end
end
You will need to explicitly map the columns, so a simple select *
is not a good idea.
Note the use of for select
, which selects zero or more rows and iterates over the cursor, and suspend
, which outputs a row to be fetched from the stored procedure (in this case for each row of the cursor).
You can produce values from this procedure like:
select column1, column2
from sp_test_procedure(10)
Related Topics
SQL Sum Data from Multiple Tables
How to Import Text Files with the Same Name and Schema But Different Directories into Database
Way to Try Multiple Selects Till a Result Is Available
Is There Common Street Addresses Database Design for All Addresses of the World
How to Check If a Stored Procedure Exists Before Creating It
Efficient SQL Test Query or Validation Query That Will Work Across All (Or Most) Databases
Is There Ever a Time Where Using a Database 1:1 Relationship Makes Sense
Replacing Null with 0 in a SQL Server Query
Insert Picture into SQL Server 2005 Image Field Using Only SQL
SQL Server: Should I Use Information_Schema Tables Over Sys Tables
What's the Difference Between "Where" Clause and "On" Clause When Table Left Join
What Is the Null Character Literal in Tsql
Pls-00428: an into Clause Is Expected in This Select Statement
Convert Text Value in SQL Server from Utf8 to Iso 8859-1