问题
I'm having an issue with creating dynamic sql statement in SQL Anywhere.
CREATE PROCEDURE pplAnalysis
AS
BEGIN
DECLARE @Sql NVARCHAR(4000)
SELECT @Sql = "select * from cds.ppl"
EXECUTE(@Sql)
END
When I execute this procedure, I get an Column 'select * from cds.ppl' not found
error.
Can you please tell me what am I doing wrong?
回答1:
The issue had to do with syntax and the RESULT
clause; after adding semicolons, RESULT
clause, and used SET
to initialize the Sql variable, here is what worked (tested in SQL Anywhere Network Server Version 12.0.1):
drop proc pplAnalysis;
CREATE PROCEDURE pplAnalysis()
RESULT (cnot CHAR(5), cnull CHAR(5), vnot VARCHAR(5), vnull VARCHAR(5), explanation VARCHAR(50))
BEGIN
DECLARE @Sql NVARCHAR(4000);
SET @Sql = 'select cnot, cnull, vnot, vnull, explanation from dbo.spaces';
EXECUTE ( @Sql );
END;
spaces
is a table in the dbo
schema and those columns are the same type specified in RESULT
Tested these two ways to execute the procedure and both returned result:
call pplAnalysis();
cnot cnull vnot vnull explanation
----- ----- ----- ----- --------------------------------------------------
Execution time: 0.027 seconds
Procedure completed
or
exec pplAnalysis;
cnot cnull vnot vnull explanation
----- ----- ----- ----- --------------------------------------------------
Execution time: 0.018 seconds
For more details:
Returning result sets from procedures
Create procedure statement
回答2:
Use single quotes.
SELECT @Sql = 'select * from cds.ppl'
回答3:
Try first saving the result of the query in a temporal table, and then do a SELECT
from the temporal table:
SELECT @Sql = "select into #temp * from cds.ppl"
EXECUTE(@Sql)
SELECT * FROM #temp
回答4:
After some research, I have edited my answer.
Regarding the EXECUTE ( string-expression )
statement, yes you have to use single quotes instead of double quotes for the string expression. This page mentions:
It lets you execute dynamically prepared statements, such as statements that are constructed using the parameters passed in to a procedure. Literal strings in the statement must be enclosed in single quotes, and the statement must be on a single line.
Which will eliminate the column not found error but the procedure will return this other error:
Result set not permitted in '<batch statement>'
Same error returned when trying to execute this statement alone:
execute ('select * from sysusers')
With probable cause:
You attempted to execute a SELECT statement in a context where a result set is not permitted.
See my most recent answer for the solution.
And regarding schemas, here's how to refer to objects:
It is always good practice to refer to database objects by a schema name and the object name, separated by a period (.). For a complete example, to SELECT records from the Employee table in the HumanResources schema of the current database would look like:
SELECT * FROM HumanResources.Employee
To reference an object located in a remote database, the fully qualified object name includes the server name and the database name. For example, to SELECT records from the Employee table in the HumanResources schema in the AdventureWorks database on MyServer would look like:
SELECT * FROM MyServer.AdventureWorks.HumanResources.Employee
I tested that in SQL Anywhere 12 and it works the same. And even though I was not familiar with schemas, what I'm suggesting you below is actually using schemas, dbowner would be the schema name:
1) select * from dbname.dbowner.tablename
2) select * from dbowner.tablename
3) select * from dbname..tablename
(assumes table exists in the dbo
schema)
Bottom line.... In your select statement cds.ppl
has to be a table named ppl
created in the cds
schema.
Or if cds
is your database name and ppl
your table name created in the dbo
schema, you are missing a dot:
select * from cds..ppl
来源:https://stackoverflow.com/questions/10234063/how-to-create-dynamic-stored-procedure-in-sql-anywhere