dynamic Select statement on declared table variable - SYBASE - select

I have one declared table variable in stored procedure,(sybase database). Data is populated in that table as needed. But now I want to select particular columns based on different conditions. I am trying dynamic SQL to do the same but not working. Can it go like I am assuming?
ALTER PROCEDURE "dbo"."sp_userMenus"
#fundName VARCHAR(20) , #userName VARCHAR(20)
AS
BEGIN
declare #tableData as table (
id int IDENTITY(1,1),
[menuDisplayName] nvarchar(100),
[menuOrder] int,
[menuType] nvarchar(100),
[parentVerticalMenu] nvarchar(100),
[parentHorizontalMenu] nvarchar(100),
[groupID] int,
[inDashboardAll] int,
[inDashboardOverview] int,
[inDetail] int,
[inSummary] int,
[isDetail] int,
[zOrder] int
)
--insert into #tableData
if #userName = 'ADMIN'
SET #SQLQuery = 'select *
from #tableData order by parentVerticalMenu, parentHorizontalMenu'
else
SET #SQLQuery = 'select menuDisplayName,menuOrder,menuType,parentVerticalMenu,parentHorizontalMenu
from #tableData order by parentVerticalMenu, parentHorizontalMenu'
EXEC sp_executesql #SQLQuery
END
getting error "Must declare the scalar variable "#tableData" OR Must declare the table variable "#tableData".

Change the code:
declare #tableData as table (
To:
CREATE TABLE #tableData (
Change the references from #tableData to #tableData
The temporary table will exist until the current session or procedure ends, or until its you drop it using drop table.

Remove the keyword 'as' prior to 'table'

Related

TSQL Create table inside case statement

The code below tries to use case condition to create a table or another. What would be the sql way to express that?
DECLARE #tmp VARCHAR(255)
SET #tmp = 'A'
SELECT CASE #tmp
WHEN 'A' THEN CREATE TABLE #Hello (ID Int, Hello varchar)
WHEN 'B' THEN CREATE TABLE #Goodbye (ID Int, Goodby varchar)
END
Instead of a CASE statement, simply use IF, since inside the CASE statement you cannot control the flow of execution of TSQL Statements or use DDL statements.
As per # Zohar Peled's comment, I am adding an arbitrary length to the varchar fields, since they had been declared without any:
DECLARE #tmp VARCHAR(255)
SET #tmp = 'A'
IF #tmp = 'A'
BEGIN
--PRINT 'Creating table #Hello'
CREATE TABLE #Hello (ID Int, Hello varchar(128))
END
ELSE
IF #tmp = 'B'
BEGIN
--PRINT 'Creating table #Goodbye'
CREATE TABLE #Goodbye (ID Int, Goodby varchar(128))
END

Functions and Triggers in PostgreSql

As I am new to DBs, I am learning PostgreSql and for a sample, I am trying to small scenario on Mobile Recharge Database System. The below is the query I have. I want to know what is the problem with the function I have written which should only return balance amount of an account number which is nothing but the customer id.
And, I also want to add the value in the wallet table when we add some value (that's topup kind of).
Please help me in this. Thanks.
The below is the complete query:
CREATE DATABASE "RECHARGESYS"
WITH OWNER = postgres
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'English_United States.1252'
LC_CTYPE = 'English_United States.1252'
CONNECTION LIMIT = -1;
--SERVICEPROVIDER TABLE:
DROP TABLE SERVICE_PROVIDERS;
CREATE TABLE SERVICE_PROVIDERS
(
SPID VARCHAR(5) PRIMARY KEY CHECK(SPID LIKE 'S%'),
SPNAME VARCHAR(50)
);
--CUSTOMER TABLE:
DROP TABLE CUSTOMER;
CREATE TABLE CUSTOMER
(
CID INT PRIMARY KEY,
CNAME VARCHAR(50)
);
--RECHARGE TABLE:
DROP TABLE RECHARGE;
CREATE TABLE RECHARGE
(
RID INT PRIMARY KEY,
CID INT REFERENCES CUSTOMER(CID),
SPID VARCHAR(5) REFERENCES SERVICE_PROVIDERS(SPID) CHECK(SPID LIKE 'S%'),
RENUMBER BIGINT,
AMOUNT INT
);
--TRANSACTION TABLE:
DROP TABLE TRANSACTION;
CREATE TABLE TRANSACTION
(
TID INT PRIMARY KEY,
SPID VARCHAR(5) REFERENCES SERVICE_PROVIDERS(SPID) CHECK(SPID LIKE('S%')),
RID INT REFERENCES RECHARGE(RID)
);
--WALLET TABLE:
DROP TABLE WALLET;
CREATE TABLE WALLET
(
WID INT PRIMARY KEY,
CID INT REFERENCES CUSTOMER(CID),
WAMOUNT INT
);
INSERT INTO SERVICE_PROVIDERS VALUES ('S1001', 'AIRTEL');
INSERT INTO SERVICE_PROVIDERS VALUES ('S1002', 'AIRCEL');
INSERT INTO SERVICE_PROVIDERS VALUES ('S1003', 'TATA DOCOMO');
INSERT INTO SERVICE_PROVIDERS VALUES ('S1004', 'IDEA');
INSERT INTO SERVICE_PROVIDERS VALUES ('S1005', 'VODAFONE');
SELECT * FROM SERVICE_PROVIDERS;
INSERT INTO CUSTOMER VALUES('20001','AHMED');
INSERT INTO CUSTOMER VALUES('20002','ASIF');
INSERT INTO CUSTOMER VALUES('20003','AHSRAF');
INSERT INTO CUSTOMER VALUES('20004','MAHESH');
INSERT INTO CUSTOMER VALUES('20005','ARUN');
SELECT * FROM CUSTOMER;
INSERT INTO WALLET VALUES('30001','20001','1000');
INSERT INTO WALLET VALUES('30002','20002','1000');
INSERT INTO WALLET VALUES('30003','20003','1000');
INSERT INTO WALLET VALUES('30004','20004','1000');
INSERT INTO WALLET VALUES('30005','20005','1000');
SELECT * FROM WALLET;
--IN THIS FUNCTION I WANT TO CHECK THE BALANCE ONCE I GIVE THE ACCOUNT NUMBER / CUSTOMER ID (ID):
CREATE OR REPLACE FUNCTION BALANCE(ACCNO INT)
RETURNS INT AS $BAL$
BEGIN
SELECT WAMOUNT INTO BAL FROM WALLET WHERE CID=ACCNO;
RETURN(BAL);
END;
$BAL$ LANGUAGE plpgsql;
SELECT BALANCE('20001') FROM WALLET;
--ALSO I WANT TRIGGER THAT CAN ADD AMOUNT TO THE WALLET.
The problem with your function is that you try to use the variable BAL without declaring it:
CREATE OR REPLACE FUNCTION BALANCE(ACCNO INT)
RETURNS INT AS $BAL$
declare BAL integer; --<--- Add this line
.......
But for a simple select query you don't need a plpgsql function. A sql function will do the job:
CREATE OR REPLACE FUNCTION balance(ACCNO INT)
RETURNS INT AS $$
SELECT wamount FROM wallet WHERE cid=ACCNO;
$$ LANGUAGE sql;

EF5 "the selected stored procedure or function returns no columns"

I am using EF 5 and this is my SP
USE [MYDatabase] GO
SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER ON GO
ALTER PROCEDURE [dbo].[SP_FirstAttend] #serviceStart date, #serviceEnd date AS
BEGIN
SET NOCOUNT OFF
SET FMTONLY OFF
--IF (1=0)
--BEGIN
--SET FMTONLY ON
BEGIN
DROP TABLE #temp1
CREATE TABLE #temp1 (id int, sid int, npi int, fiscal int, serviceStart date, serviceEnd date, fcode varchar(10), tid int, StudName varchar(200), TherName varchar (200))
INSERT INTO #temp1
SELECT ID,
mand.SID,
mand.NPI,
FiscalYear,
ServiceStart,
ServiceEnd,
FundingCode,
ther.TID,
RTRIM(stud.StudentLastName) + ' ' + RTRIM(stud.StudentFirstName),
RTRIM(ther.LastName) + ' ' + RTRIM(ther.FirstName)
FROM MandateMaster AS mand
JOIN TherapistMaster AS ther ON ther.NPI = mand.NPI
JOIN StudentMaster AS stud ON stud.SID = mand.SID
SELECT *,
(SELECT top(1) sid
FROM SessionDetail
WHERE SID = tb1.sid
AND TID = tb1.tid) AS val1
FROM #temp1 AS tb1
WHERE ServiceStart >= #serviceStart
AND ServiceStart <= #serviceEnd;
END
-- END
END
and its still giving me "Stored procedure returns no columns".
I read somewhere to set the
integrated security=True; in the connection string on web.config but still nothing worked.
I been trying to find the solutions for this but keep getting the same message. Please let me know what to do .
Thanks.
You got nothing as result because this condition IF (1=0) always returns false then your select statement is never hit.
Just remove this IF (1=0) and your stored procedure will return some data.

How to use openxml within a user defined function in SQL Server

I have an XML structure that I parse using OPENXML within a stored procedure to retrieve parameters used to perform a query. This procedure was a base procedure that a different stored procedure (procedure 2) is calling. Procedure 2 uses an insert-exec construct to get the data from the base procedure. This works great as long as we only call Procedure 2 or the base procedure.
My first problem is that I have a different procedure (procedure 3) that now needs to get the result from procedure 2 (I need the business rules that this procedure enforces), but cannot due to the message:
An INSERT EXEC statement cannot be nested.
I then tried to take the base procedure and make it a table valued function, but when I execute it, I receive the message:
Only functions and some extended stored procedures can be executed from within a function.
How do I get around one or both of these issues?
EDIT 1
I am including a code snippet to show the base procedure (Procedure 1) and the procedure implementing business requirements on the results of that procedure (Procedure 2). If there is a 3rd procedure that needs the results with the business rules applied, we run into problems.
create procedure dbo.p_Proc
#Xml xml
as
begin
set nocount on;
declare #l_idoc int
, #InfoId int
, #InfoTypeId int
, #Id int
, #Name varchar(50)
, #StatusId int
, #RoleId int
, #XmlBase xml
, #l_path varchar(100);
declare #T_TABLE table(
InfoId int
, InfoTypeId int
);
declare #T_RESULT table
(
Field1 int
, Field2 varchar(50)
, Field3 int
);
EXEC sp_xml_preparedocument #l_idoc OUTPUT, #Xml;
set #l_path = '/xml/Info';
insert into #T_TABLE(InfoId, InfoTypeId)
select InfoId, InfoTypeId
from OPENXML (#l_idoc, #l_path, 1)
with (
InfoId int './#InfoId'
, InfoTypeId int './#InfoTypeId'
);
select #InfoId = InfoId
, #InfoTypeId = InfoTypeId
from #T_TABLE;
-- create the XML to call the base widgets
select #XmlBase =
(
select *
from
(
select t.Id, t.Name, t.StatusId, t.RoleId
from #T_TABLE w
inner join dbo.T_TABLE2 t
on t.InfoId = w.InfoId
and t.InfoTypeId = w.InfoTypeId
) b
for xml raw('Widget'), root('Xml')
);
-- retrieve widgets from base security
insert into #T_RESULT(Field1, Field2, Field3)
exec dbo.p_ProcBase #Xml = #XmlBase;
-- apply business logic here
select w.Field1, w.Field2, w.Field3
from #T_RESULT w;
end;
go
create procedure dbo.p_ProcBase
#Xml xml = null
as
begin
set nocount on;
declare #l_idoc int
, #Id int
, #Name varchar(50)
, #StatusId int
, #RoleId int
, #l_path varchar(100);
declare #T_Table table(
Id int
, Name varchar(50)
, StatusId int
, RoleId int
);
EXEC sp_xml_preparedocument #l_idoc OUTPUT, #Xml;
set #l_path = '/Xml/Widget';
insert into #T_Table(Id, Name, StatusId, RoleId)
select Id, Name, StatusId, RoleId
from OPENXML (#l_idoc, #l_path, 1)
with (
ProjectId int './#Id'
, WidgetTypeName varchar(50) './#Name'
, WorkflowStatusId int './#StatusId'
, UserRoleId bigint './#RoleId'
);
select #Id = w.Id
, #Name = w.Name
, #StatusId = w.StatusId
, #RoleId = w.RoleId
from #T_Table w;
-- retrieve enabled widgets for which the user has a role in the current workflow state
select t.Field1, t.Field2, t.Field3
from dbo.T_TABLE t
where t.StatusId = #StatusId
and t.RoleId = #RoleId;
end;
In order to send a data set (table) between procs, you must use a Table type, store the output of proc2 in a variable of table type and add a readonly only table type parameter to proc3
First you must create a table type to map your output from proc2:
CREATE TYPE T_RESULT AS TABLE
(
Field1 int
, Field2 varchar(50)
, Field3 int
);
In dbo.p_Proc change #T_RESULT to:
declare #T_RESULT T_RESULT
Then create proc3:
CREATE PROCEDURE dbo.proc3
#T_RESULT T_RESULT READONLY
AS
BEGIN
SET NOCOUNT ON
INSERT INTO T3(...)
SELECT ... FROM #T_RESULT
END
Don't forget to add READONLY after a table type parameter in a proc.

Is it possible to use local table variables in a procedure inside an sql query contained in a VARCHAR variable?

I have the following code:
DECLARE #temp_table_1 TABLE (id int identity(0, 1), col_1 varchar(50)),
#txtVar VARCHAR(MAX)
INSERT INTO #temp_table_1
SELECT col_1 FROM table_1 -- This table_1 is a real table in the database.
Set #txtVar = 'SELECT * FROM #temp_table_1'
EXECUTE (#txtVar)
The error I get is
Declare variable #temp_table_1.
How can I fix this?
Set #txtVar = 'SELECT * FROM myTable WHERE column_value=''' + #var1 + ''''
This article will help you get a basic ideas of dynamic sql.
EDIT
It is not possible to use table variables in a dynamic query.
You have to use temporary table or Use custom TABLE type.
Temporary table
CREATE TABLE #temp_table_1
(
id INT IDENTITY(0, 1),
col_1 VARCHAR(50)
)
DECLARE #txtVar VARCHAR(MAX)
INSERT INTO #temp_table_1
SELECT col_1
FROM table_1 -- This table_1 is a real table in the database.
SET #txtVar = 'SELECT * FROM #temp_table_1'
EXECUTE (#txtVar)
DROP TABLE #temp_table_1
Custom Table Type
CREATE TYPE DefaultTable AS TABLE (ID INT IDENTITY(0, 1), COL_1 VARCHAR(50))
GO
-- Fill a var of that type with some test data
DECLARE #MyTable DefaultTable
INSERT #MyTable
SELECT col_1 FROM table_1 -- This table_1 is a real table in the database.
-- Now this is how you pass that var into dynamic statement
EXECUTE sp_executesql N'SELECT * FROM #MyTable',
N'#MyTable DefaultTable READONLY',
#MyTable