Dynamic SQL select parameters
Until runtime I don't know the table name and column-name on which I have to do a select.
Here is my SQL:
SELECT single <b>w_sum_col_name </b> FROM (w_tbl_name)
INTO ZOH_AUDIT-ZOH_NET1
WHERE REQUID = ZOH_AUDIT-REQUID.
My SQL fails when I have SUM(any_column) in the string w_sum_col_name. However it works if its a just a column name of the table. Failure is when the w_sum_col_name string has an aggregate function.
Error is ..SAPSQL_ILLEGAL_AGGREGATE" CX_SY_DYNAMIC_OSQL_SYNTAX
Any alternatives for my requirement is appreciated.
Try this code.
REPORT zreport NO STANDARD PAGE HEADING MESSAGE-ID zfi
LINE-COUNT 65
LINE-SIZE 120.
PARAMETERS: p_matnr LIKE mara-matnr.
DATA: mytable LIKE dd02l-tabname,
fields(50) TYPE c OCCURS 0 WITH HEADER LINE,
labst LIKE mard-labst.
TABLES: mard.
DEFINE select_statement.
select (&1) into &2
from (&3)
where matnr = p_matnr.
endselect.
END-OF-DEFINITION.
fields = 'SUM( LABST )'.
APPEND fields.
mytable = 'MARD'.
select_statement fields[] labst 'MARD'.
WRITE:/ labst.
Similar Messages
-
Dynamic PL/SQL block vs dynamic SQL SELECT
Hi there,
I have a question regarding the optimal way to code a dynamic SELECT INTO statement. Below are the 2 posiibilities I know of:
_1. Dynamically executing the SELECT statement and making use of the INTO clause of the EXECUTE IMMEDIATE statement_
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'SELECT COUNT(*) FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job';
EXECUTE IMMEDIATE v_query_str
INTO v_num_of_employees
USING p_job;
RETURN v_num_of_employees;
END;
_2. Encapsulating the SELECT INTO statement in a block and dynamically exectuting the block_
CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2)
RETURN NUMBER
IS
v_query_str VARCHAR2(1000);
v_num_of_employees NUMBER;
BEGIN
v_query_str := 'begin
SELECT COUNT(*) INTO :into_bind FROM emp_'
|| p_loc
|| ' WHERE job = :bind_job;
end;';
EXECUTE IMMEDIATE v_query_str
USING out v_num_of_employees, p_job;
RETURN v_num_of_employees;
END;
I was just wondering which way would be preferred? I know the second method uses a bind variable for the INTO clause, but does the first one also use bind varialbes (no semi-colon)? Any differences in terms of efficiency or speed?
Thanks alot
Edited by: BYS2 on Oct 19, 2011 1:23 AMsybrand_b wrote:
No difference in terms of performance or speed
Both variants will wreck the primary purpose of PL/SQL: to avoid parsing.
When I would see a 'developer' do this, I would fire him on the spot.
Why abuse PL/SQL in such a fashion? Both statements don't require parsing, as there is nothing dynamic in them and indicate a complete lack of understanding of Oracle, or a desire to deliver completely unscalable applications, resulting in end-users desiring to lynch you, and rightly so.
Remove the dynamic SQL or find another job.
Sybrand Bakker
Senior Oracle DBANot dynamic? What if p_loc and p_job were generated dynamically based on user-input? or what if there were potentially thousands of tables that p_loc could refer to? Should I make a CASE statement with a thousand cases?
In addition, the first example was actually taken directly from the official Oracle Database Application Developer's Guide (version 10.2). http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_dynamic_sql.htm#i1006429 - look under 'Sample Single-Row Query Using Native Dynamic SQL' heading. Therefore, if you have any issues with this alleged 'improper' usage of dynamic SQL, perhaps you should go talk to Oracle directly.
While I appreciate your response, I don't think it has occurred that you that not everyone is a 'developer'. In fact, I have only very recently (several days ago) taught myself how to use Oracle SQL, PL/SQL and XMLDB by reading several of the official Oracle language and developer's guides. It is more a passing interest to me as I am working on some medical research which may require the use of a database. I am actually in medical school at the moment but have an undergraduate degree in Electrical and Computer engineering so I am generally well-versed in programming.
Perhaps the next time, you post your rubbish, rude and unhelpful comments, you should stop and think that people come to this forum because they need help and not because they want to be told to 'find another job'. In fact, I am quite certain that I could make you look absolutely stupid in any topic of electrical engineering or medicine.
Please do us all a favour and stop polluting this forum with your vapid posts. While I understand that your behavior is likely a compensatory mechanism to cope with your inferiority complex, know that help IS available if you need it.
Edited by: BYS2 on Oct 19, 2011 2:13 AM -
Dynamic Sql Select Query : getting no response
Hi
I am working on a synchronous interface that has jdbc at the receiver side..
I need to be doing a select dynamically based on a filed from the request like
select locationId from dbTablename where empId = 'xxx' AND delFlag =0
the xxx will be populated from a filed in the request
For this i have set up a request structure with action as "SQL_QUERY" and the following query in the access field
SELECT location_id from dbtablename where empID='$cv_EMPID$' and delFlag=0
I have a key element which has a sub-element "cv_EMPID"
Unfortunately, the query doestn pull any records from the dbtable..
In sxmb_moni , I get a query like this
- <STATEMENT>
- <TABLENAME action="SQL_QUERY">
<TABLE>tablename</TABLE>
</TABLENAME>
<access>select cv_locationID from tablename where cv_empID='$cv_EmpID$'</access>
- <key>
<cv_EmpID>60000016</cv_EmpID>
</key>
</STATEMENT>
but there is no response
What do u think is the problem here?
Thanks
KrishnaHi,
Refer these links:
http://help.sap.com/saphelp_nw70/helpdata/en/b0/676b3c255b1475e10000000a114084/content.htm
RDBMS system integration using XI 3.0 JDBC Sender/Receiver adapter
SYNCHRONOUS SOAP TO JDBC - END TO END WALKTHROUGH
Check out this-
http://help.sap.com/saphelp_erp2005vp/helpdata/en/2e/96fd3f2d14e869e10000000a155106/content.htm
Also check that, JDBC driver is installed correctly- for this
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/3867a582-0401-0010-6cbf-9644e49f1a10
Check out these links
http://help.sap.com/saphelp_nw04/helpdata/en/64/ce4e886334ec4ea7c2712e11cc567c/content.htm
http://help.sap.com/saphelp_nw04/helpdata/en/2e/96fd3f2d14e869e10000000a155106/content.htm
JDBC Receiver Adapter -- Synchronous Select Step by Step
Regards,
Nithiyanandam -
Dynamic SQL Select String VS non-dynamic USING Clause
This isn’t a question, I just wanted to share a solution to a problem I have encountered several times.
e.g. You have ‘n’ number of variables, of which any combination could be used in a SQL string. But it’s difficult to execute the SQL string with USING without an unpleasant CASE statement.
Solution: Reference all ‘n’ bind variables in the FROM clause of the SQL in an in-line-view. And specify all variables in the USING Clause.
When building the SQL String, specify the view.variable rather than directly referencing bind variables
This eliminates the requirement to check which variables have been populated.
<h6>
t_select := ‘SELECT tab.cola, tab.colb’;
t_from := ‘FROM (SELECT :1 cola, :2 colb, :3 colc, :4 cold, :5 cole) parms, tablea tab’;
t_where := ‘WHERE tab.cola = parms.cola’;
OPEN c t_select||t_from||t_where USING v1, v2, v3, v4, v5;
</h6>
I hope this is useful to someone...
PeteDInteresting approach.. but I would still prefer creating a DBMS_SQL cursor instead - as there the binding can be fully controlled at run-time.
If this has to return a ref cursor (caller is an external process), then I would rather use conditional processing logic (as that is what PL is about) in PL/SQL and build a "+proper+" SQL statement (with only the required bind variables) at run-time. Features like polymorphism makes this easy - and the call interface that is provided to the client is a lot cleaner. -
Dynamic SQL select from unknown table until runtime
I need to do a select from a table that is unknown until runtime. Is there any good examples of this. The Store Procedure will take in the table name and return a row.
I am not using inline SQL because there is a lot more complexity involved . What I need to do is understand how to reference this unknown table.
Here is an example of what I have written so far.
PACKAGE pk_LoadNativeDataItems IS
PROCEDURE version;
TYPE RowDataCur IS REF CURSOR;
PROCEDURE pr_LoadNativeDataItems(p_flag IN NUMBER
p_how_many_rows_to_fetch IN NUMBER,
p_row_data OUT RowDataCur);
PROCEDURE pr_LoadNativeDataItems(p_flag IN NUMBER
p_how_many_rows_to_fetch IN NUMBER,
p_table_name IN VARCHAR,
p_row_data OUT RowDataCur) IS
BEGIN
OPEN p_row_data FOR
SELECT * from ||p_table_name||;
END pr_LoadNativeDataItems;
END pk_LoadNativeDataItems;
Thanks for any help
TonyHere is example for similar question:
Using variables for tables and columns -
Dynamic SQL statement in a Procedure
Hi,
is it possible to use a variable in place of a column name in a sql statement inside a procedure. Or to create the whole statement as a sql statement and execute it (preferrably with parameters - rather than concatinating the values).
Thanks for any help or direction
ElliotTurns out you can do the following very nicely (dynamic sql with parameterized values)
Declare
id number(10,0);
sql_stmt varchar2(300);
fieldName varchar2(30);
fieldValue varchar2(100);
id := 30;
fieldName := 'somecolumn';
fieldValue := 'some value';
sql_stmt := 'UPDATE myTable SET ' || fieldName || ' = :1 WHERE id = :2';
EXECUTE IMMEDIATE sql_stmt USING fieldValue, id; -
Writing to a temp table in a stored procedure with dynamic sql
Hi
I am writing into a temp table with dynamic sql:
select coloum_name into #temp_table from
+
@DestinationDBName+'.information_schema.tables
and then I am trying to use #temp_table in the procedure:
select coloum_name into #anotherTable from #temp_table
but I am getting an error that #temp_table is not recognized.
Can a temp table not be used in dynamic sql ?
How can I overcome this problem ?Temp Table Can used easily in Dynamic Query in SQL Server and here is small Exmaple you can check it and do like it
CREATE PROC test
AS
BEGIN
CREATE TABLE #T1
(ID int , NAME Nvarchar(50))
CREATE TABLE #T2
(ID int , NAME Nvarchar(50))
DECLARE @SQL NVARCHAR(MAX)='Insert into #T1
SELECT database_id , Name FROM Sys.Databases
Insert into #T2 Select ID , Name from #T1 '
EXEC SP_ExecuteSQL @SQL
SELECT * FROM #T2
DROP TABLE #T1
DROP TABLE #T2
END
Exec Test
If you found My reply is helpful for you please vote me
thanks
Mustafa EL-Masry
Principle Database Administrator & DB Analyst
SQL Server MCTS-MCITP
M| +966 54 399 0968
MostafaElmasry.Wordpress.Com -
Dynamic parameter selection from infoview not storing the sql password
We are having the problem of dynamic parameter selection from infoview not storing the sql password as it does for the actual report. We are using Crystal Reports XI Release 2 version 11.5.3.438 (Not sure of SP level, asked in separate thread).
To be more specific.
We have created a report that dynamically populates the parameters of the report by pulling the records from the Informix sql database and allowing selection from there.
In the Central Management Console for the report object we have set as follows:
Process - Database:
Use original database logon information from the report - the sql username and pw etc
Use same database logon as when report is run
Process - Parameters
In selecting a default selection there is the option to put in the sql password, however, this does not stick and clears after update.
As such the end result is that every time this report is run from infoview and a user chooses a parameter (there are 5), crystal goes through some timeout for about a minute or so and then requests the sql password, if a user then selects the next parameter, the same timeout and password dialog appears.
We need the crystal report to handle to the sql password for fetching the parameters as well as for the database section of running the report, however, the parameters insists on the end user always putting the password in.
This is 100% replicatable on our system.
Any way that we can fix this?
Will an update fix this issue? If so could you please advise which one?
ThanksHi,
I am having the exact same problem. Any help?
And what does "Use same database logon as when report is run" mean? For me that would be that no prompt is needed for getting values in a dynamic parameter...
Regards
Magnus -
Passing table names as parameters (aka Trouble building a dynamic SQL command)
I am attempting to develop a template for publishing some data, and would like to pass standard table names as parameters to the various queries. What I have created generates the following error:
Msg 137, Level 16, State 1, Procedure spPublishTrans_FlashersCaution, Line 68
Must declare the scalar variable "@tmpTable".
I thought I was declaring it properly ?
Thanks.
DECLARE @FeatureClass as Nvarchar(MAX) = 'Trans_FlashersCaution'
DECLARE @ED as Nvarchar(MAX) = 'edgis.dbo.' + @FeatureClass
DECLARE @tmpTable TABLE
[OBJECTID] [int] NOT NULL,
[Id] [int] NULL,
[Location] [nvarchar](60) NULL,
[Zone] [nvarchar](5) NULL,
[Shape] [geometry] NULL
DECLARE @tmpTableParam AS NVARCHAR (MAX) = @tmpTable
SELECT @tmpTableParam
DECLARE @execquery AS NVARCHAR(MAX)
SET @execquery = 'INSERT INTO' + @tmpTableParam +
[OBJECTID]
,[Id]
,[Location]
,[Zone]
,[Shape]
SELECT
[OBJECTID]
,[Id]
,[Location]
,[Zone]
,[Shape]
FROM' + @ED;
EXECUTE sp_executesql @execqueryAlways PRINT the SQL string prior to execution when developing dynamic SQL script:
PRINT @execquery
--EXECUTE sp_executesql @execquery
Second step, test the printed SQL script for validity.
Dynamic SQL: http://www.sqlusa.com/bestpractices/dynamicsql/
Kalman Toth Database & OLAP Architect
SQL Server 2014 Database Design
New Book / Kindle: Beginner Database Design & SQL Programming Using Microsoft SQL Server 2014 -
Insert into using a select and dynamic sql
Hi,
I've got hopefully easy question. I have a procedure that updates 3 tables with 3 different update statements. The procedure goes through and updates through ranges I pass in. I am hoping to create another table which will pass in those updates as an insert statement and append the data on to the existing data.
I am thinking of using dynamic sql, but I am sure there is an easy way to do it using PL/SQL as well. I have pasted the procedure below, and what I'm thinking would be a good way to do it. Below I have pasted my procedure and the bottom is the insert statement I want to use. I am faily sure I can do it using dynamic SQL, but I am not familiar with the syntax.
CREATE OR REPLACE PROCEDURE ACTIVATE_PHONE_CARDS (min_login in VARCHAR2, max_login in VARCHAR2, vperc in VARCHAR2) IS
BEGIN
UPDATE service_t SET status = 10100
WHERE poid_id0 in
(SELECT poid_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
DBMS_OUTPUT.put_line( 'Service Status:' || sql%rowcount);
UPDATE account_t SET status = 10100
WHERE poid_id0 IN
(SELECT account_obj_id0 FROM service_t
WHERE poid_type = '/service/telephony'
AND login >= min_login AND login <= max_login);
DBMS_OUTPUT.put_line( 'Account Status:' || sql%rowcount);
UPDATE account_nameinfo_t SET title=Initcap(vperc)
WHERE obj_id0 IN
(SELECT account_obj_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >=min_login AND login <= max_login);
DBMS_OUTPUT.put_line('Job Title:' || sql%rowcount);
INSERT INTO phone_card_activation values which = 'select a.status, s.status, s.login, to_char(d.sysdate,DD-MON-YYYY), ani.title
from account_t a, service_t s, account_nameinfo_t ani, dual d
where service_t.login between service_t.min_login and service_t.max_login
and ani.for_key=a.pri_key
and s.for_key=a.pri_key;'
END;
Thanks for any advice, and have a good weekend.
GeordieCorrect my if I am wrong but aren't these equal?
UPDATE service_t SET status = 10100
WHERE poid_id0 in
(SELECT poid_id0 FROM service_t
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
(update all the records where there id is in the sub-query that meet the WHERE Clause)
AND
UPDATE service_t SET status = 10100
WHERE poid_type='/service/telephony'
AND login >= min_login AND login <= max_login);
(update all the records that meet the WHERE Clause)
This should equate to the same record set, in which case the second update would be quicker without the sub-query. -
Does the XSQL servlet support dynamic SQL? Take a stock screening page as an example. In this example you want to dynamically build the where clause based on user input. Thus if a Minimum PE Ratio of 3 was entered, the where clause of "where PE_Ratio >= 3" would be appended to the query. In this case there may be up to 20 different parameters or more to be mapped dynamically, so it wouldn't be feasible to nest all of the different combinations.
XSQL Supports lexical substitution parameters
so any and every part of any query can be parameterized.
The extreme case is:
<query> {@sql} </query>
where the entire query is passed in
in a parameter (named "sql").
But any combination of parameters
and substitutions is legal and can
be used to do what you want.
Since the variables are not BIND
variabled, but instead lexical
substitution variables, you can
do things like:
<query>
select {@collist}
from {@table}
where {@where}
order by {@orderby}
</query>
You can provide default parameter values
using XML attributes on the <query>
element which then can be overridden
if a value is passed in in the request...
<query collist="ename, sal"
orderby="sal desc"
where="1=1"
from="dept">
select {@collist}
from {@table}
where {@where}
order by {@orderby}
</query>
And then a request to the page
can pass in a orderby=decode(comm,null,1,0)
or something to override the defaults.
null -
Hello All,
Been looking into this for a couple of days, and I keep hitting brick walls, so I'm hoping someone can offer me a bit of inspiration. What I'm trying to do is write a stored procedure that lets the user specify a list of tables, and an output directory, and the SP creates a series of BCP statements that export these tables to comma delimited files.
This wouldn't be too hard, but I need to output the field headings in the first row of the table (and use quotes as text qualifiers). I'm doing this by looping round sys.columns, pulling out all the fieldnames, creating two select statements, and UNION ALL-ing them together. e.g.......
select 'FIELD1','FIELD2','FIELD3','FIELD4'
union all
select field1,field2,field3,field4 from tablename
It all works fine until you try it on a table with a lot of columns. Although you can build a big SQL statement in an NVARCHAR(MAX), BCP only appears to read the first 4000 characters of it, so it fails.
To get round this, I've moved all of the code that builds the big SQL statement to its own stored procedure (i.e. you pass the tablename, and it returns the table with the field names in the first row). Then, I can just call this new SP in my BCP statement, with a couple of parameters.
The problem I'm getting is BCP is complaining saying '[Microsoft][SQL Native Client]BCP host-files must contain at least one column'. I'm setting no count off, and there are no print statements, so I'm assuming this is because the data is getting returned via an exec sp_executesq (although this is a guess). I can't think of a way round this though, as the SQL need to be dynamic.
alter PROCEDURE [dbo].[sp_QBMultiFileExportGetData]
@tablename varchar(100),
@dbname varchar(100)
AS
BEGIN
declare @Execstring as nvarchar(MAX)
declare @currentfieldname as varchar(100)
declare @selectlist as varchar(8000)
declare @fieldnamelist as varchar(8000)
declare @colnames table
columnname varchar(100)
begin
set nocount on
set @execstring='select COLUMN_NAME '+
'from ' + @dbname + '.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ''' + @tablename + ''''
insert into @colnames(columnname)
exec sp_executesql @execstring
set @selectlist=''
set @fieldnamelist=''
--Loop through fieldnames, and build two strings
--One for outputting fieldnames and one for selecting the actual data
while exists(select * from @colnames)
begin
select top 1 @currentfieldname=columnname from @colnames
set @selectlist=@selectlist + 'quotename(['+ @currentfieldname + '],char(34)),'
set @fieldnamelist=@fieldnamelist + '''' + @currentfieldname + ''' [' +@currentfieldname + '],'
delete from @colnames where columnname=@currentfieldname
end
--remove last quote
set @selectlist=substring(@selectlist,1,len(@selectlist)-1)
set @fieldnamelist=substring(@fieldnamelist,1,len(@fieldnamelist)-1)
--Built string to execute, with fieldnames, and select fields
set @execstring='select ' + @fieldnamelist + ' union all select ' + @selectlist + ' from ' + @dbname + '..' + @tablename
return exec sp_executesql @execstring
end
END
this returns exactly what I want, but when I try to use it in a BCP statement, I get the error....
i.e.
EXEC master..xp_cmdshell 'bcp "exec QCDev.dbo.sp_QBMultiFileExportGetData ''tablename'',''dbname''" queryout C:\\outputfile.txt -T -t","'
Error = [Microsoft][SQL Native Client]BCP host-files must contain at least one column
Anyone ever tried this before?Hi Guys,
Thanks for the suggestions. I had been trying to avoid temp tables (don't really like them), but I think eventually, they were the only way to go. Unfortunately, this opened a whole can of scoping worms, and after a couple of hours, its all given me a right headache. However, the good news is I've finally got it working as I wanted.
I was finding I was having issues using temp tables, as the tables being used were dynamic, so I would have to create them in a dynamic SQL string, and they weren't propagating upwards from child to parent. I seemed to be getting the same problem using global temporary tables too, although I'm not sure why, as they should have worked They seemed to be out of scope by the time the SP that was calling my sp_QBMultiFileExportGetData tried to output the data. This might possibly have been because BCP wasn't seeing the same scope, but I've not tested it fully (and its very possible I was making a mistake).
The solution was to abandon sp_QBMultiFileExportGetData, and merge the code back into the calling script. However, rather than trying to pass an enormous SQL string to bcp, running it separately with sp_executesql, and dumping the results in a global temp table. Then let bcp just call a 'select * from temptable', to avoid the select statement getting too long. Its not the most elegant solution, but it seems to work fine.
ALTER PROCEDURE [dbo].[sp_QBMultiFileExport]
-- Add the parameters for the stored procedure here
@tablenames varchar(1000), --list of tables to be exported
@outputpath varchar(1000), --output path ***AS SEEN BY THE SERVER, NOT THE CLIENT***
@servername varchar(100), --Server where data resides
@dbname varchar(100), --database name
@delimiter varchar(1) --output delimiter
AS
BEGIN
declare @Execstring as nvarchar(max)
declare @currenttable as varchar(100)
declare @colnames table
columnname varchar(100)
declare @currentfieldname as varchar(100)
declare @selectlist as varchar(max)
declare @fieldnamelist as varchar(max)
--Get rid of CRLFs in the tablenames parameter
set @tablenames=replace(@tablenames,char(10),'')
set @tablenames=replace(@tablenames,char(13),'')
--add extra comma to the end of the list (needed later for consistency)
set @tablenames=@tablenames+','
--Get first table in the list
set @currenttable=substring(@tablenames,1,charindex(',',@tablenames)-1)
while @tablenames<>''
begin
--Get a list of fieldnames from syscols
insert into @colnames(columnname)
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @currenttable
set @selectlist=''
set @fieldnamelist=''
while exists(select * from @colnames)
begin
--get first column name
select top 1 @currentfieldname=columnname from @colnames
--add to select statement lists
set @selectlist=@selectlist + 'quotename(['+ @currentfieldname + '],char(34)),'
set @fieldnamelist=@fieldnamelist + '''' + @currentfieldname + ''' [' +@currentfieldname + '],'
--remove column from temptable
delete from @colnames where columnname=@currentfieldname
end
--remove last quote from field lists
set @selectlist=substring(@selectlist,1,len(@selectlist)-1)
set @fieldnamelist=substring(@fieldnamelist,1,len(@fieldnamelist)-1)
--check for temp table, and drop if necessary
IF object_id('tempdb..##MultiFileExportTempTable') IS NOT NULL
BEGIN
DROP TABLE ##MultiFileExportTempTable
END
--Build list of fieldnames, and select list, unioned together
--and put the results in temptable
set @execstring='select ' + @fieldnamelist + ' into ##MultiFileExportTempTable union all select ' + @selectlist + ' from ' + @dbname + '..' + @currenttable
exec sp_executesql @execstring
--get BCP to pull data back from ##temptable, and dump in file
set @execstring='EXEC master..xp_cmdshell ''bcp "select * from ##MultiFileExportTempTable" queryout ' + @outputpath + '\' + @currenttable + '.txt' + ' -c -T -t"' + @delimiter + '"'''
exec sp_executesql @execstring
--drop tablename from list
set @tablenames=replace(@tablenames,@currenttable + ',','')
--if tablenames list is not empty, get the next one
if @tablenames<>''
set @currenttable=substring(@tablenames,1,charindex(',',@tablenames)-1)
else
set @currenttable=''
end
IF object_id('tempdb..##MultiFileExportTempTable') IS NOT NULL
BEGIN
DROP TABLE ##MultiFileExportTempTable
END
END
So, you call this with...
exec dbo.[sp_QBMultiFileExport] 'table1,table2,table3',filepath,servername,dbname,delimiter
...and it creates delimited files called table1.txt, table2.txt and table3.txt in the specified folder, with field headings and text qualifiers.
Many thanks for all your suggestions -
Report using ref cursor or dynamic Sql
Hi,
I never create a report using a ref cursor or a dynamic sql. Could any one help me to solve the below issue.
I have 2 tables.
1. Student_Record
2. Student_csv_help
Student_Record the main table where the data is stored.
Student_csv_help will contain the all the column names of the Student_record.
CREATE TABLE Student_CSV_HELP
ENTRY_ID NUMBER,
RAW_NAME VARCHAR2(40 BYTE),
DESC_NAME VARCHAR2(1000 BYTE),
IN_OUTPUT_LIST VARCHAR2(1 BYTE)
SET DEFINE OFF;
Insert into TOA_CSV_HELP
(ENTRY_ID, RAW_NAME, DESC_NAME, IN_OUTPUT_LIST)
Values
(1, 'S_ID', 'Student ID', 'Y');
Insert into TOA_CSV_HELP
(ENTRY_ID, RAW_NAME, DESC_NAME, IN_OUTPUT_LIST)
Values
(2, 'S_Name', 'Student Name', 'Y');
Insert into TOA_CSV_HELP
(ENTRY_ID, RAW_NAME, DESC_NAME, IN_OUTPUT_LIST)
Values
(3, 'S_Join_date', 'Joining Date', 'Y');
Insert into TOA_CSV_HELP
(ENTRY_ID, RAW_NAME, DESC_NAME, IN_OUTPUT_LIST)
Values
(4, 'S_Address', 'Address', 'Y');
Insert into TOA_CSV_HELP
(ENTRY_ID, RAW_NAME, DESC_NAME, IN_OUTPUT_LIST)
Values
(5, 'S_Fee', 'Tution Fee', 'N');
commit;
CREATE TABLE Student_record
S_ID NUMBER,
S_Name VARCHAR2(100 BYTE),
S_Join_date date,
S_Address VARCHAR2(360 BYTE),
S_Fee Number
Insert into Student_record
(S_ID, S_Name, S_Join_date, S_Address,S_Fee)
Values
(101, 'john', TO_DATE('12/17/2009 08:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'CA-94777', 2000);
Insert into Student_record
(S_ID, S_Name, S_Join_date, S_Address,S_Fee)
Values
(102, 'arif', TO_DATE('12/18/2009 08:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'CA-94444', 3000);
Insert into Student_record
(S_ID, S_Name, S_Join_date, S_Address,S_Fee)
Values
(103, 'raj', TO_DATE('12/19/2009 08:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'CA-94555', 2500);
Insert into Student_record
(S_ID, S_Name, S_Join_date, S_Address,S_Fee)
Values
(104, 'singh', TO_DATE('12/20/2009 08:00:00', 'MM/DD/YYYY HH24:MI:SS'), 'CA-94666', 2000);
Commit;
Now my requirement is:
I have a form with Student_record data block. When i Click on print Button on this form. It will open another window which has Student_CSV_HELP.DESC_NAME and a check box before this.
The window look like as below:
check_box DESC_NAME+
X S_ID+
-- S_Name+
X S_Join_date+
X S_Address+
-- S_Fee+
X means check box checked.+
-- means check box Unchecked.+
After i selected these check boxes i will send 2 parameters to the report server
1. a string parameter to the report server which has the value 'S_ID,S_Join_date,S_Address' (p_column_name := 'S_ID,S_Join_date,S_Address');
2. the s_id value from the student_record block (p_S_id := '101');
Now my requirement is when i click on run. I need a report like as below:
Student ID : 101+
Joining Date : 12/17/2009 08:00:00+
Address : CA-94777+
This is nothing but the ref cursor should run like as below:
Select S_id from student_record block S_id = :p_S_id;
Select S_Join_date from student_record block S_id = :p_S_id;
Select S_Address from student_record block S_id = :p_S_id;
So, according to my understanding i have to select the columns at the run time. I dont have much knowledge in creating reports using ref cursor or dynamic sql.
So please help me to solve this issue.
Thanks in advance.Plain sql should satisfy your need. Try ....
Select S_id, S_Join_date, S_Address
from student_record
where S_id = :p_S_id -
Help Needed in Dynamic Sql or alternate to Dynamic Sql
Hi Am working in sqlserver 2008 R2 and here is my Table structure and SPC
;create table SalaryReport(IdSalary int primary key identity(1,1),
IDMainCompany int,IDSubCompany int,Salary money,Incentive int,NoofEmployees int, SalaryDate datetime, Creditscore int );
insert into SalaryReport (IDMainCompany,IDSubCompany,Salary,Incentive,NoofEmployees,SalaryDate,Creditscore)
( Select 100 as IDMainCompany , 1000 as IDSubCompany ,200000 AS Salary, 20000 as Incentive, 500 as NoofEmployees,
'2014-01-01' as SalaryDate, 60 as Creditscore union all
Select 100 as IDMainCompany , 1001 as IDSubCompany ,300000 AS Salary, 40000 as Incentive, 600 as NoofEmployees,
'2014-01-01' as SalaryDate , 70 as Creditscore union all
Select 100 as IDMainCompany , 1002 as IDSubCompany ,400000 AS Salary, 40000 as Incentive, 1500 as NoofEmployees,
'2014-01-01' as SalaryDate , 45 as Creditscore union all
Select 101 as IDMainCompany , 1003 as IDSubCompany ,30000 AS Salary, 2000 as Incentive, 100 as NoofEmployees,
'2014-01-01' as SalaryDate, 60 as Creditscore union all
Select 102 as IDMainCompany , 1004 as IDSubCompany ,450000 AS Salary, 25000 as Incentive, 700 as NoofEmployees,
'2014-01-01' as SalaryDate, 30 as Creditscore)
Sample Test Script:
DECLARE @IDMainCompany int = 100;
DECLARE @Process_Date datetime = '2014-01-01';
declare @Query nvarchar(max);
SELECT
CAST(SR.IDMainCompany AS VARCHAR(12)) AS IDMainCompany
,CAST(SR.IDSubCompany AS VARCHAR(12)) AS IDSubCompany
,CAST(SR.Salary AS VARCHAR(12)) AS Salary
,CAST(SR.Incentive AS VARCHAR(12)) AS Incentive
,CAST(SR.NoofEmployees AS VARCHAR(12)) AS NoofEmployees
,CAST(SR.SalaryDate AS VARCHAR(15)) AS SalaryDate
,CAST((SR.Creditscore) AS VARCHAR(15)) AS average
FROM SalaryReport SR
WHERE SR.IDMainCompany = @IDMainCompany
AND DATEPART(MM, SR.SalaryDate) = DATEPART(MM, @Process_Date)
UNION ALL
SELECT
'' AS IDMainCompany
,'' AS IDSubCompany
,'Total: ' + CAST(SUM(SR.Salary) AS VARCHAR(12)) AS Salary
,'Total: ' + CAST(SUM(SR.Incentive) AS VARCHAR(12)) AS Incentive
,'Total: ' + CAST(SUM(SR.NoofEmployees) AS VARCHAR(12)) AS NoofEmployees
,'' AS SalaryDate
,'Total: ' +CAST(avg(SR.Creditscore) AS VARCHAR(12)) AS Totalaverage
FROM SalaryReport SR
WHERE SR.IDMainCompany = @IDMainCompany
AND DATEPART(MM, SR.SalaryDate) = DATEPART(MM, @Process_Date)
group by IDMainCompany, DATEPART(MM, SalaryDate)
the sample data i posted is having less columns. actually i have 20 columns in the select list. Also the parameters to the where condition i gave two i.e IDMainCompany, SalaryDate. I will also need to use IDSubCompany for some case. My skeleton will be
Create Procedure Test(@IDMainCompany int, @IDSubCompany int = null, @SalaryDate datetime)
as
BEGIN
IF(@IDMainCompany is not null && @IDMainCompany > 0 && @SalaryDate is not null && @SalaryDate <> ' ' &&
@IDSubCompany is null)
BEGIN
--The logic what discussed on previous posts will falls here with @IDMainCompany, @SalaryDate as parameter to the where condition
END
IF(@IDMainCompany is not null && @IDMainCompany > 0 && @SalaryDate is not null && @SalaryDate <> ' ' &&
@IDSubCompany is null && @IDSubCompany > 0 )
BEGIN
--The logic what discussed on previous posts will falls here with @IDMainCompany, @SalaryDate,@IDSubCompany as parameter to the where condition
END
END
As said i need to include 20 columns in the select list and as union all used on the previous sample there are 20 columns on the first query and 20 columns on the second query after the union all. The SPC will become big. If i repeat this for second if condition,
it will be too big. How can i reduce this writing more lines.
I am aware of the concept dynamic sql. Is there any other way to do this? or if dynamic sql is the only option, can anyone help me rewriting this select statements as dynamic sql
Could anyone please assist me
loving dotnet>>
thanks for your reply and yes, i am invoking this from my asp.net application using C# language. Would you like to share something?
<<
Yes,
You can use client side dynamic sql. I'm not talking about concatenating strings. I'm talking about using Runtime Text Tamplates (preprocesed templates in Visual Studio 2010).
Add a new "Runtime Text Template" item to your VS project. Be "MyReportTemplate.tt" the file name of the runtime text template. The content of this file should be something like the following:
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
SELECT
-- part of your query goes here
-- the interesting part come next
FROM
SalaryReport SR
WHERE
SR.IDMainCompany = @IDMainCompany
<# if (IDSubCompany.HasValue && IDSubCompany.Value > 0) { #>
AND SR.IDSubCompany = @IDSubCompany
<# } #>
AND
DATEPART(MM, SR.SalaryDate) = DATEPART(MM, @Process_Date)
GROUP BY
IDMainCompany, DATEPART(MM, SalaryDate)
Add a new c# code file named MyReportTemplate.partial.cs closed to MyReportTemplate.tt with the following code:
public partial class MyReportTemplate
public int? IDSubCompany { get; set; }
Then, to execute the query you can write a code similar to the following:
public DataTable ExecuteReport(int mainCompanyId, int? subCompanyId, DateTime processDate )
using (var cn = CreateConnection())
using (var cmd = new SqlCommand())
using (var adapter = new SqlDataAdapter(cmd))
cmd.Connection = cn;
var template = new MyReportTemplate
IDSubCompany = subCompanyId
cmd.CommandText = template.TransformText();
cmd.Parameters.AddWithValue("@IDSubCompany", subCompanyId == null ? (object) DBNull.Value : subCompanyId.Value);
cmd.Parameters.AddWithValue("@IDMainCompany", mainCompanyId);
cmd.Parameters.AddWithValue("@Process_Date", processDate);
var table = new DataTable();
adapter.Fill(table);
return table;
EntityLite: A Lightweight, Database First, Micro ORM -
Help required in changing to str for dynamic sql
Hi
I am trying to make this to string for dynamic sql, this is a part of the sql which is giving problem with p_..as parameters from proc. Help me in this , iam also seeing dbms _output but stil unable to format it to required error free string.
|| ' AND ( po.abbreviationprojectopportid LIKE '
|| '%'
|| 'NVL'
|| '('
|| p_opp_code
|| ', ''NULL'')'
|| '%'
|| ' OR co.companyname LIKE '
|| '%'
|| 'NVL'
|| '('
|| p_client_name
|| ', '' NULL'')'
|| '%'
|| ' OR le.line_item_amount = NVL '
|| ' ('
|| p_booking_amt
|| ', -0.197) '
|| 'OR po.dealcurrency = NVL '
|| '('
|| p_currency
|| ',''NULL'')'
|| 'OR be.booking_entry_id LIKE '
|| '%'
|| 'NVL ('
|| p_entry_id
|| ',''NULL'')'
|| '%'
|| ' OR le.line_item_id LIKE '
|| '%'
|| 'NVL ('
|| p_line_item
|| ',''null'')'
|| '%'
|| ' OR be.ticket_num LIKE '
|| '%'
|| 'NVL ('
|| p_ticket_num
|| ',''NULL'')'
|| '%'
|| ' OR be.updatedby LIKE '
|| '%'
|| 'NVL ('
|| p_user_name
|| ',''NULL'')'
|| '%'
|| ' OR credittransaction.acct_code ='
|| 'NVL ('
|| p_gl_account
|| ','
|| '-0.197)'
|| 'OR debittransaction.acct_code ='
|| 'NVL ('
|| p_gl_account
|| ', '
|| '-0.197) '
|| 'OR credittransaction.profit_ctr_code ='
|| 'NVL ('
|| p_profit_center
|| ','
|| ' -0.197)'
|| 'OR debittransaction.profit_ctr_code ='
|| 'NVL ('
|| p_profit_center
|| ','
|| '-0.197)'
|| ' OR le.sap_posting = NVL ('
|| p_sap_posting
|| ',''$'')'
|| 'OR cmis.cmis_code = NVL ('
|| p_cmis_nominal
|| ','' -0.197)'
|| 'OR sa.sap_code = NVL ('
|| p_sap_booking_entity
|| ', -0.197)'
|| ' OR (be.booking_date BETWEEN '
|| v_booking_date_from
|| 'AND '
|| v_booking_date_to
|| ')'
|| ' )'
|| 'ORDER BY '
|| p_sort_by
|| ' '
|| p_order;some errors.. Try this...
' SELECT be.booking_date bookingdate, '
|| ' be.booking_entry_id entryid, le.line_item_id itemid,'
|| ' po.abbreviationprojectopportid opportunitycode,'
|| ' co.companyname clientname, '
|| ' le.line_item_amount bookingamount,'
|| ' be.ticket_num ticketnum, po.dealcurrency currency,'
|| ' cmis.cmis_code cmis_nominal,'
|| ' sa.sap_code sap_booking_entity,'
|| ' (SELECT full_name '
|| ' FROM iba_employee '
|| ' WHERE TO_CHAR (employeeid) = be.updatedby) updatedby,'
|| ' be.updateddate updateddate, '
|| ' (SELECT le.line_item_amount * rate '
|| ' FROM iba_currencyconversion '
|| ' WHERE tocurrencycd = '
|| 'USD'
|| ' AND currencycd = po.dealcurrency '
|| ' AND conversiondate = be.booking_date) amountusd,'
|| 'debittransaction.acct_code debitglaccount,'
|| ' credittransaction.acct_code creditglaccount,'
|| ' debittransaction.profit_ctr_code debitprofitcenter,'
|| ' credittransaction.profit_ctr_code creditprofitcenter,'
|| ' debittransaction.amt debitamount,'
|| ' credittransaction.amt creditamount'
|| ' FROM rb_booking_entry be, '
|| ' rb_line_item le, '
|| ' rb_booking_period bp,'
|| ' rb_cmis_gl_account cmisgl,'
|| ' rb_cmis_account cmis,'
|| ' iba_projectopportunity po,'
|| ' iba_company co,'
|| ' rb_sap_account sa,'
|| ' (SELECT acctr.line_item_id line_item,'
|| ' sapgl_acc.account_code acct_code,'
|| ' acctr.amount amt,'
|| ' sappr.profit_center_code profit_ctr_code'
|| ' FROM rb_account_transaction acctr,'
|| ' rb_sap_profit_center sappr,'
|| ' rb_sap_gl_account sapgl_acc'
|| ' WHERE acctr.profit_center_id = sappr.profit_center_id '
|| ' AND acctr.gl_account_id = sapgl_acc.gl_account_id '
|| ' AND acctr.transaction_type = ''D'') debittransaction,'
|| ' (SELECT acctr.line_item_id line_item,'
|| ' sapgl_acc.account_code acct_code,'
|| ' acctr.amount amt,'
|| ' sappr.profit_center_code profit_ctr_code '
|| ' FROM rb_account_transaction acctr, '
|| ' rb_sap_profit_center sappr, '
|| ' rb_sap_gl_account sapgl_acc '
|| ' WHERE acctr.profit_center_id =sappr.profit_center_id '
|| ' AND acctr.gl_account_id = sapgl_acc.gl_account_id '
|| ' AND acctr.transaction_type = ''C'') credittransaction '
|| ' WHERE po.projectopportunityid = be.projectopportunityid '
|| ' AND be.booking_entry_id = le.booking_entry_id '
|| ' AND po.companyid = co.companyid '
|| ' AND bp.booking_period_id = be.booking_period_id '
|| ' AND cmis.cmis_id = cmisgl.cmis_id '
|| ' AND le.sap_id = sa.sap_id '
|| ' AND le.cmis_id = cmis.cmis_id '
|| ' AND debittransaction.line_item(+) = le.line_item_id '
|| ' AND credittransaction.line_item(+) = le.line_item_id '
|| ' AND ( po.abbreviationprojectopportid LIKE ' || '''%' || NVL(p_opp_code,'NULL') || '%'''
|| ' OR le.line_item_id LIKE '
|| '''%'
|| NVL (
|| p_line_item
|| ,'null')
|| '%'''
| ' OR le.line_item_amount = '
||NVL(|| p_booking_amt, -0.197)
|| ' OR po.dealcurrency ='
|| NVL(p_currency,'NULL')
|| ' OR be.booking_entry_id LIKE '
|| '''%'
|| NVL (p_entry_id,'NULL')
|| '%'''
|| ' OR be.ticket_num LIKE '
|| '''%'
|| NVL (p_ticket_num,'NULL')
|| '%'''
|| ' OR be.updatedby LIKE '
|| '''%'
|| NVL (p_user_name,'NULL')
|| '%'''
|| ' OR credittransaction.acct_code ='
|| NVL (p_gl_account,-0.197)
|| ' OR debittransaction.acct_code ='
|| NVL (p_gl_account, -0.197)
|| ' OR credittransaction.profit_ctr_code ='
|| NVL (p_profit_center, -0.197)
|| ' OR debittransaction.profit_ctr_code ='
|| NVL (p_profit_center, -0.197)
|| ' OR le.sap_posting = '
||NVL (p_sap_posting,'$')
|| ' OR cmis.cmis_code = '
||NVL (p_cmis_nominal, -0.197)
|| ' OR sa.sap_code = '
|| NVL (p_sap_booking_entity, -0.197)
|| ' OR (be.booking_date BETWEEN to_date('''
|| v_booking_date_from
|| ''') AND to_date('''
|| v_booking_date_to
|| ''')'
|| ' OR co.companyname LIKE '
|| '''%'
|| NVL(p_client_name,'NULL')
|| '%'''
|| ' )'
|| 'ORDER BY ' || p_sort_by || ',' || p_order;
Maybe you are looking for
-
i cant use facetime. but my sister can. we share the same account for itunes.but when i go to facetime on my ipod touch and click on create a new account a blank screen pops up and the only thing it says is cancel and account. what do i do?
-
HT201320 how do i delete an old email account from my iPhone 4?
Phone keeps receiving mail from old account but not current one, can I delete the original e-mail account?
-
Install Windows 7 on external drive and boot iMac from it?
Hi everyone, I want to use Windows 7 on my iMac, I would like to install Windows 7 on an external drive and boot my iMac from this external drive. Is this possible? If yes, any good tutorials? (I am aware of virtual machines, but am wondering if I ca
-
CREATING A PDF THAT OPENS TO 'FIT IN WINDOW'
Using InDesign (I'm CS2) is it possible to create a pdf with a default setting so that no matter who opens it (with Acrobat) it will open to 'fit in window'? Is this a creator defined attribute? I know that one can set their preferences in Acrobat so
-
Native non English application
Hi, We are developping an apex aplication which is for only a Dutch audience. Since Apex is not available in Dutch yet, a lot of the default strings and messages are in English. What do we need to do? Do we have to develop the whole application in En