I have written a sql query like
DECLARE #OpenDays VARCHAR(15)
SET #OpenDays = (SELECT LTRIM(RTRIM(REPLACE(SUBSTRING(OpenDays,3,LEN(OpenDays)),' - ','')))
FROM
(
SELECT DISTINCT
STUFF((SELECT ' - ' + CONVERT(VARCHAR(30),SSF.OpenDayOfWeek )
FROM #FacilityDayOpen SSF
FOR XML PATH('')
), 1, 2, ' ') as OpenDays
FROM #FacilityDayOpen S
) TS
)
How to convert this query into LINQ
it looks like a stored procedure I can recommend you use the following program
http://sqltolinq.com/
but you might want to replace you #values with values you think may work in query and then you so you can check if it working
Related
I have a select query which is working in postgres , but not in Oracle
The Select Query Uses regexp_split_to_array , which is not suppourted in Oracle
The regexp_split_to_array used here is to filter non working days
select
*
from
department
where
dept_status = 'A'
AND NOT (
#{DAY} = any ( regexp_split_to_array(lower(non_working_days), ',')))
AND dept_loc = 'US'
http://sqlfiddle.com/#!4/fbac4/4
Oracle does not have a function regexp_split_to_array . Instead you can use LIKE (which is much faster than regular expressions) to check for a sub-string match (including the surrounding delimiters so you match a complete term):
SELECT *
FROM department
WHERE dept_status = 'A'
AND ',' || lower(non_working_days) || ',' NOT LIKE '%,' || :DAY || ',%'
AND dept_loc = 'US'
Note: You should pass in variables using bind variables such as :day or ? (for an anonymous bind variable) rather than relying on a pre-processor to replace strings as it will help to prevent SQL injection attacks.
fiddle
SELECT DISTINCT 'update loc_final_2 set county = ''' || TRIM(upper(county) ) || '''
where city = '''
|| TRIM(upper(city) ) || ''' and state = ''' || TRIM(upper(state) ) || ''';'
FROM audtr_rgn_assgnmnts;
commit
can somebody tell me what the above query does. There's a table called loc_final_2 and another one called audtr_rgn_assgnmnts. I don't understand what the query is doing and I need to improve this query. But before that I have to understand what it is doing. I also need to know what commit is doing at the end.
The query is trying to generate multiple update statements for the table loc_final_2 using the values from audtr_rgn_assgnmnts.
I'm not sure why the commit exists there as the queries are not being executed.
If at all the intention of the original coder of the query was to run multiple updates, then I would say it's a wrong approach. A single update / MERGE like this would be more straightforward and performant.
UPDATE loc_final_2 l
SET
county = (
SELECT upper(TRIM(county) ) --Add MIN/MAX if there are multiple rows
FROM audtr_rgn_assgnmnts a
WHERE l.city = upper(TRIM(a.city) ) AND l.state = upper(TRIM(a.state) )
);
MERGE INTO loc_final_2 t USING audtr_rgn_assgnmnts s ON (
l.city = upper(TRIM(a.city) ) AND l.state = upper(TRIM(a.state) )
)
WHEN MATCHED THEN UPDATE SET t.county = UPPER(TRIM(s.county));
If there are multiple rows, you would need to do a select distinct in the USING
MERGE INTO loc_final_2 t USING (
SELECT DISTINCT city,
state,
upper(TRIM(s.county) ) AS county
FROM audtr_rgn_assgnmnts
)
s ON (
l.city = upper(TRIM(a.city) ) AND l.state = upper(TRIM(a.state) )
)
WHEN MATCHED THEN UPDATE SET t.county = s.county;
EDIT :
what is the 3-single quote doing in the query
A literal quote in Oracle needs to be escaped using another single quote.
So, If your final query needs to have something like a='b' , the expression generating that string should be a=||'''b||''' one the quite itself, one quote to escape that quote, other the part of concatenation.
because min/max can be used only for numbers, right?
MAX and MIN can be used on strings. Here I said you may use it to avoid duplicate values for same county returned from the inner query. DISTINCT is also an option if you don't want to use MIN/MAX.
Following is sample query.
CREATE PROCEDURE GetModel
(
#brandids varchar(100), -- brandid="1,2,3"
#bodystyleid varchar(100) -- bodystyleid="1,2,3"
)
AS
select * from model
where brandid in (#brandids) -- use a UDF to return table for comma delimited string
and bodystyleid in (#bodystyleid)
My requirement is that if #brandids or #bodystyleid is blank, query should return all rows for that condition.
Please guide me how to do this? Also suggest how to write this query to optimize performance.
You'll need dynamic SQL or a split function for this anyway, since IN ('1,2,3') is not the same as IN (1,2,3).
Split function:
CREATE FUNCTION dbo.SplitInts
(
#List VARCHAR(MAX),
#Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN ( SELECT Item = CONVERT(INT, Item) FROM (
SELECT Item = x.i.value('(./text())[1]', 'int') FROM (
SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(#List, #Delimiter, '</i><i>')
+ '</i>').query('.') ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y
WHERE Item IS NOT NULL
);
Code becomes something like:
SELECT m.col1, m.col2 FROM dbo.model AS m
LEFT OUTER JOIN dbo.SplitInts(NULLIF(#brandids, ''), ',') AS br
ON m.brandid = COALESCE(br.Item, m.brandid)
LEFT OUTER JOIN dbo.SplitInts(NULLIF(#bodystyleid, ''), ',') AS bs
ON m.bodystyleid = COALESCE(bs.Item, m.bodystyleid)
WHERE (NULLIF(#brandids, '') IS NULL OR br.Item IS NOT NULL)
AND (NULLIF(#bodystyleid, '') IS NULL OR bs.Item IS NOT NULL);
(Note that I added a lot of NULLIF handling here... if these parameters don't have a value, you should be passing NULL, not "blank".)
Dynamic SQL, which will have much less chance of leading to bad plans due to parameter sniffing, would be:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'SELECT columns FROM dbo.model
WHERE 1 = 1 '
+ COALESCE(' AND brandid IN (' + #brandids + ')', '')
+ COALESCE(' AND bodystyleid IN (' + #bodystyleid + ')', '');
EXEC sp_executesql #sql;
Of course as #JamieCee points out, dynamic SQL could be vulnerable to injection, as you'll discover if you search for dynamic SQL anywhere. So if you don't trust your input, you'll want to guard against potential injection attacks. Just like you would if you were assembling ad hoc SQL inside your application code.
When you move to SQL Server 2008 or better, you should look at table-valued parameters (example here).
if(#brandids = '' or #brandids is null)
Begin
Set #brandids = 'brandid'
End
if(#bodystyleid = '' or #bodystyleid is null)
Begin
Set #bodystyleid = 'bodystyleid'
End
Exec('select * from model where brandid in (' + #brandids + ')
and bodystyleid in (' + #bodystyleid + ')')
I'm using JDBC, I have to set array of values to a single column,
I know it works in Hibernate and Ibatis but it seems to be hard to get it working Pure JDBC sql.
I have an array of String values
names[] = new String[]{"A","B","C"};
and a Query like
select * from emp where name in(?)
I tried pstmt.setObject(1,names), it is not working..
This is not supported in pure JDBC. You have to generate a query so that the in clause contains one placeholder for each element of the array.
Spring's JDBC helper classes support named parameters and what you want to do.
This will work with the following Syntax:
"SELECT * FROM emp WHERE name IN ( SELECT column_value FROM TABLE( ? ) )"
pmst.setArray( 1, conn.createArrayOf( "VARCHAR", names ) );
I have a dynamic PL/SQL that will construct the SELECT statement based on what the searching criteria input from the users,likes:
l_sql := 'SELECT * INTO FROM TABLEA WHERE 1=1 ';
IF in_param1 IS NOT NULL THEN
l_sql := l_sql || 'AND column1 = in_param1 ';
END IF;
IF in_param2 IS NOT NULL THEN
l_sql := l_sql || 'AND column2 = in_param2 ';
END IF;
...................................
IF in_paramXX IS NOT NULL THEN
l_sql := l_sql || 'AND columnXX = in_paramXX ';
END IF;
To reduce the hard parse overhead , I consider to use the binding variables. However , it is difficult to manage when supplying the actual values to the binding variables as there are so many binding variables and combination of the generated SELECT statement . I cannot use the method of DBMS_SESSION.set_context() introduced at http://www.dba-oracle.com/plsql/t_plsql_dynamic_binds.htm because my account has no right to use this package. Besides , I want the generated SQL only contains the conditions on the fields that the user did not leave empty. So I cannot change the dynamic SQL to something likes
SELECT * INTO FROM TABLEA WHERE 1=1
and ( in_param1 is NULL or column1 = in_param1)
and ( in_param2 is NULL or column2 = in_param2)
...............................................
and ( in_paramXX is NULL or columnXX = in_paramXX)
So , I want to try to use the DBMS_SQL method .Can anyone give an example about how to use DBMS_SQL to call dynamic SQL with binding variables? Especially , how can I get the result executed from DBMS_SQL.execute() to the SYS_REFCURSOR , something like :
open refcursor for select .... from
The oracle version that I use is 10g and it seems that the oracle 10g does not have DBMS_Sql.To_Refcursor()
In your Oracle version you can apply some tricks to your query in order to do this. The idea is to use a query in the following form:
select *
from
(select
:possibleParam1 as param1
-- do the same for every possible param in your query
:possibleParamN as paramN
from dual
where rownum > 0) params
inner join
-- join your tables here
on
-- concatenate your filters here
where
-- fixed conditions
then execute it with:
open c for query using param1, ..., paramN;
It works by using DUAL to generate a fake row with every single param, then inner joining this fake row to your real query (without any filters) using only the filters you want to apply. This way, you have a fixed list of bind variables in the SELECT list of the params subquery, but can control which filters are applied by modifying the join condition between params and your real query.
So, if you have something like, say:
create table people (
first_name varchar2(20)
last_name varchar2(20)
);
you can construct the following query if you just want to filter on first name
select *
from
(select
:first_name as first_name,
:last_name as last_name
from dual
where rownum > 0) params
inner join
people
on
people.first_name = params.first_name;
and this if you want to filter on both first_name and last_name
select *
from
(select
:first_name as first_name,
:last_name as last_name
from dual
where rownum > 0) params
inner join
people
on
people.first_name = params.first_name and
people.last_name = params.last_name;
and in every case you would execute with
open c for query using filterFirstName, filterLastName;
It is important for performance to use the where rownum > 0 with DUAL as it forces Oracle to "materialize" the subquery. This usually makes DUAL stop interfering with the rest of the query. Anyway, you should check the execution plans to be sure Oracle is not doing anything wrong.
In 10g a DBMS_SQL cursor can't be changed into a Ref Cursor. Going through a result set through DBMS_SQL is tortuous since, as well as looping through the rows, you also have to loop through the columns in a row.
I want the generated SQL only contains
the conditions on the fields that the
user did not leave empty
Is that purely for performance reasons ? If so, I suggest you work out what the practical execution plans are and use separate queries for them.
For example, say I'm searching on people and the parameters are first_name, last_name. gender, date_of_birth. The table has indexes on (last_name,first_name) and (date_of_birth), so I only want to allow a query if it specifies either last_name or date_of_birth.
IF :p_firstname IS NOT NULL and :p_lastname IS NOT NULL THEN
OPEN cur FOR
'SELECT * FROM PEOPLE WHERE last_name=:a AND first_name=:b AND
(date_of_birth = :c or :c is NULL) AND (gender = :d or :d IS NULL)' USING ....
ELSIF :p_lastname IS NOT NULL THEN
OPEN cur FOR
'SELECT * FROM PEOPLE WHERE last_name=:a AND
(date_of_birth = :c or :c is NULL) AND (gender = :d or :d IS NULL)' USING ....
ELSIF :p_dateofbirth IS NOT NULL THEN
OPEN cur FOR
'SELECT * FROM PEOPLE WHERE date_of_birth=:a AND
(first_name=:b OR :b IS NULL) AND (gender = :d or :d IS NULL)' USING ....
ELSE
RAISE_APPLICATION_ERROR(-20001,'Last Name or Date of Birth MUST be supplied);
END IF;