i am having a problem with my SQL query that I wrote in Sql Server 2008 Express SMS and am using inside of Visual Studio 2010.
Basics: There is an input box on a web page. It is used to search for a persons name, address, id, etc. When I use a persons name on the website, or inside of the built in Visual Studio Server Explorer, such as "Kargul" (made up), it won't return any results using my Stored Procedure. However, in SQL Server 2008 Express SMS, the same Stored Procedure returns a valid result.
Is there something I am missing? Here is my Procedure:
SET NOCOUNT ON;
DECLARE #vars NVARCHAR(50);
SET #vars = '%' + #searchTerm + '%';
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.FirstName LIKE (#vars)
UNION
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.LastName LIKE (#vars)
UNION
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.Street1 LIKE (#vars)
UNION
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.City LIKE (#vars)
UNION
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.PersonId LIKE (#vars)
UNION
SELECT a.PersonId, Stat.StatusId, a.Honorific, a.FirstName, a.LastName, a.Street1, a.Street2, a.City, a.State, a.Zip, a.Phone, a.Email FROM Persons AS a
JOIN dbo.PersonStatus as Stat
ON a.StatusId = Stat.StatusId
WHERE
a.State LIKE (#vars)
ORDER BY PersonId;
Run a profiler trace on the server to see what is executing when run through VS2010; Is it possible the search parameter is not getting passed? Or maybe you need a SET NOCOUNT ON in your proc.
Related
I have a select statement in the form of string in a Variable. This sql select statement could be of any complexity.
I have to extract different clauses ( select , from , where , group by etc ) from it. As I need to addend some code based on my business need into these clause, and remake the entire sql
SELECT Accounts_Dly.Country
AS Country,
Accounts_Dly.LE_Book
AS LE_Book,
TRIM (TO_CHAR (Trans_Count_Feed_Stg.TRAN_DATE, 'dd/mm/rrrr'))
AS TRAN_DATE,
Accounts_Dly.Currency
AS Currency,
Accounts_Dly.Account_No
AS Account_No,
Accounts_Dly.Account_Name
AS Account_Name,
Accounts_Dly.Vision_GL
AS Vision_GL,
Accounts_Dly.Vision_OUC
AS Vision_OUC,
TRIM (
TO_CHAR (Trans_Count_Feed_Stg.TRAN_AMT,
'999,999,999,999,999,990.00'))
AS TRAN_AMT,
Trans_Count_Feed_Stg.PART_TRAN_TYPE
AS PART_TRAN_TYPE,
Trans_Count_Feed_Stg.TRAN_PARTICULAR
AS TRAN_PARTICULAR,
Trans_Count_Feed_Stg.TRAN_ID
AS TRAN_ID,
Trans_Count_Feed_Stg.ENTRY_USER_ID
AS ENTRY_USER_ID,
Trans_Count_Feed_Stg.PSTD_USER_ID
AS PSTD_USER_ID
FROM Trans_Count_Feed_Stg Trans_Count_Feed_Stg
LEFT JOIN Accounts_Dly_View Accounts_Dly
ON trans_count_feed_stg.Country = accounts_dly.Country
AND trans_count_feed_stg.LE_Book = accounts_dly.LE_Book
AND trans_count_feed_stg.Contract_id = accounts_dly.account_no
WHERE Accounts_Dly.Country = 'RW'
AND Accounts_Dly.LE_Book = '01'
AND Trans_Count_Feed_Stg.TRAN_DATE BETWEEN '01-APR-2019'
AND '30-APR-2019'
AND Accounts_Dly.Account_No LIKE '20__0245007001'
Group by Accounts_dly.Country;
I want to split above sql statement like below using regex:
1.SELECT Accounts_Dly.Country
AS Country,
Accounts_Dly.LE_Book
AS LE_Book,
TRIM (TO_CHAR (Trans_Count_Feed_Stg.TRAN_DATE, 'dd/mm/rrrr'))
AS TRAN_DATE,
Accounts_Dly.Currency
AS Currency,
Accounts_Dly.Account_No
AS Account_No,
Accounts_Dly.Account_Name
AS Account_Name,
Accounts_Dly.Vision_GL
AS Vision_GL,
Accounts_Dly.Vision_OUC
AS Vision_OUC,
TRIM (
TO_CHAR (Trans_Count_Feed_Stg.TRAN_AMT,
'999,999,999,999,999,990.00'))
AS TRAN_AMT,
Trans_Count_Feed_Stg.PART_TRAN_TYPE
AS PART_TRAN_TYPE,
Trans_Count_Feed_Stg.TRAN_PARTICULAR
AS TRAN_PARTICULAR,
Trans_Count_Feed_Stg.TRAN_ID
AS TRAN_ID,
Trans_Count_Feed_Stg.ENTRY_USER_ID
AS ENTRY_USER_ID,
Trans_Count_Feed_Stg.PSTD_USER_ID
AS PSTD_USER_ID
2.FROM Trans_Count_Feed_Stg Trans_Count_Feed_Stg
LEFT JOIN Accounts_Dly_View Accounts_Dly
ON trans_count_feed_stg.Country = accounts_dly.Country
AND trans_count_feed_stg.LE_Book = accounts_dly.LE_Book
AND trans_count_feed_stg.Contract_id = accounts_dly.account_no
3.WHERE Accounts_Dly.Country = 'RW'
AND Accounts_Dly.LE_Book = '01'
AND Trans_Count_Feed_Stg.TRAN_DATE BETWEEN '01-APR-2019'
AND '30-APR-2019'
AND Accounts_Dly.Account_No LIKE '20__0245007001'
4.Group by Accounts_dly.Country
select Customer_Name from Customer where Customer_Id IN
(select distinct Customer.Customer_Id from Customer join Toy_Rental on Toy_Rental.Customer_ID=Customer.Customer_Id
order by Toy_Rental.Total_Amount desc
fetch next 2 rows only);
There's no FETCH clause in 11g; it is available in 12c.
See if this helps:
select a.Customer_Name
from Customer a
where a.Customer_Id IN (select x.customer_id
from (select c.Customer_Id
from Customer c join Toy_Rental t on t.customer_id = c.customer_id
order by t.total_amount desc
) x
where rownum <= 2
)
Alternatively:
with cust as
(select c.customer_id
row_number() over (order by t.total_amount desc) rn
from customer c join toy_rental t on t.customer_id = c.customer_id
)
select a.customer_name
from customer a join cust x on x.customer_id = a.customer_id
where x.rn <= 2
I used some online converter to convert my view in MySQL to oracle and the result was this:
CREATE VIEW actor_info
AS
SELECT
a.actor_id,
a.first_name,
a.last_name,
GROUP_CONCAT(DISTINCT ||(c.name, ': ',
(SELECT GROUP_CONCAT(f.title FROM dual ORDER BY f.title SEPARATOR FROM dual ', ')
FROM film f
INNER JOIN film_category fc
ON f.film_id = fc.film_id
INNER JOIN film_actor fa
ON f.film_id = fa.film_id
WHERE fc.category_id = c.category_id
AND fa.actor_id = a.actor_id
)
)
ORDER BY c.name SEPARATOR '; ')
AS film_info
FROM actor a
LEFT JOIN film_actor fa
ON a.actor_id = fa.actor_id
LEFT JOIN film_category fc
ON fa.film_id = fc.film_id
LEFT JOIN category c
ON fc.category_id = c.category_id
GROUP BY a.actor_id, a.first_name, a.last_name;
The converter didn't convert too well so I had to modify the query and end up with something like this:
CREATE VIEW actor_info
AS
SELECT
a.actor_id,
a.first_name,
LISTAGG(c.name || ': ',
(SELECT LISTAGG(f.title, ', ') within group (order by f.title)
FROM film f
INNER JOIN film_category fc
ON f.film_id = fc.film_id
INNER JOIN film_actor fa
ON f.film_id = fa.film_id
WHERE fc.category_id = c.category_id
AND fa.actor_id = a.actor_id
)
) WITHIN group (order by c.name)
AS film_info
FROM actor a
LEFT JOIN film_actor fa
ON a.actor_id = fa.actor_id
LEFT JOIN film_category fc
ON fa.film_id = fc.film_id
LEFT JOIN category c
ON fc.category_id = c.category_id
GROUP BY a.actor_id, a.first_name, a.last_name, c.name;
But I'm still getting multiple errors like I can't use distinct in the first listagg or that argument should be a constant or a function of expression in GROUP BY. I'm out of ideas to try to solve this, any suggestions on what the error is or another way to do this view?
Oracle's listagg() doesn't support distinct internally, which is a bit of a pain. The other error you're getting, ORA-30497, is because you've accidneally mad ethe second listagg() call the delmiter for the first one.
It's a little hard to tell without sample data and expected resulsts, but it appears you're looking for something like:
SELECT a.actor_id, a.first_name, a.last_name,
LISTAGG(c.name || ': ' || (
SELECT LISTAGG(f.title, ', ') WITHIN GROUP (ORDER BY f.title)
FROM film f
INNER JOIN film_actor fa
ON fa.film_id = f.film_id
INNER JOIN film_category fc
ON f.film_id = fc.film_id
WHERE fc.category_id = c.category_id -- from main query
AND fa.actor_id = a.actor_id -- from main query
), '; ') WITHIN GROUP (ORDER BY c.name)
AS film_info
FROM actor a
LEFT JOIN (
SELECT DISTINCT fa.actor_id, c.category_id, c.name
FROM film_actor fa
LEFT JOIN film_category fc
ON fc.film_id = fa.film_id
LEFT JOIN category c
ON c.category_id = fc.category_id
) c
ON c.actor_id = a.actor_id
GROUP BY a.actor_id, a.first_name, a.last_name;
The 'distinct' part is achieved with the inline view, and the inner listagg then only needs to find all films for that category/actor.
I have three selects
SELECT
mam.fecha fecha
, u.COD_USUARIO usuario
, u.NOMBREAPELLIDOS nombre
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha ASC) AS rn_asc
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha DESC) AS rn_desc
,mam.accion accion
,u.ID_CENTRO_GESTION centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'A'
and trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy')
and mam.cod_usuario = '9717703'
and u.id_centro_gestion = '3'
order by u.cod_usuario
Second one, it is the same changing the where
SELECT
mam.fecha fecha
, u.COD_USUARIO usuario
, u.NOMBREAPELLIDOS nombre
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha ASC) AS rn_asc
, ROW_NUMBER() OVER (PARTITION BY u.cod_usuario ORDER BY mam.fecha DESC) AS rn_desc
,mam.accion accion
,u.ID_CENTRO_GESTION centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'D'
and trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy')
and mam.cod_usuario = '9717703'
and u.id_centro_gestion = '3'
order by u.cod_usuario
Thrid one
SELECT COUNT (*) numeroincidencias, ri.cod_usuario usuario
FROM r_incidencias ri
WHERE TRUNC (ri.fecha_inc) = TO_DATE ('13/09/2018', 'dd/mm/yyyy')
and ri.cod_usuario = '9717703'
GROUP BY ri.cod_usuario
I want to link these select by cod_usuario. It couldn't be rows in the first, second or third select.
How can I do an outer join of these selects?
Make each of your selects a common table expression, then full outer join them together:
WITH cte1 AS (SELECT mam.fecha AS fecha,
u.COD_USUARIO AS usuario,
u.NOMBREAPELLIDOS AS nombre,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha DESC) AS rn_desc,
mam.accion AS accion,
u.ID_CENTRO_GESTION AS centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u
ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'A' and
trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy') AND
mam.cod_usuario = '9717703' AND
u.id_centro_gestion = '3'
order by u.cod_usuario),
cte2 AS (SELECT mam.fecha AS fecha,
u.COD_USUARIO AS usuario,
u.NOMBREAPELLIDOS AS nombre,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha ASC) AS rn_asc,
ROW_NUMBER() OVER (PARTITION BY u.cod_usuario
ORDER BY mam.fecha DESC) AS rn_desc,
mam.accion AS accion
u.ID_CENTRO_GESTION AS centrogestion
FROM r_mod_asignar_material mam
INNER JOIN r_usuarios u
ON mam.cod_usuario = u.cod_usuario
where mam.ACCION = 'D' and
trunc(mam.fecha) = to_date('13/09/2018','dd/mm/yyyy') AND
mam.cod_usuario = '9717703' AND
u.id_centro_gestion = '3'
order by u.cod_usuario),
cte3 AS (SELECT COUNT (*) numeroincidencias,
ri.cod_usuario usuario
FROM r_incidencias ri
WHERE TRUNC (ri.fecha_inc) = TO_DATE ('13/09/2018', 'dd/mm/yyyy') AND
ri.cod_usuario = '9717703'
GROUP BY ri.cod_usuario)
SELECT *
FROM cte1
FULL OUTER JOIN cte2
ON cte2.cod_usuario = cte1.cod_usuario
FULL OUTER JOIN cte3
ON cte3.cod_usuario = COALESCE(cte1.cod_usuario, cte2.cod_usuario)
I have 2 CTE.When i try to join them i get an error message "ORA-01789: ".how can i merge the 2 CTE.Is there any other way to get the desired result?
WITH IMPORT_CTE
AS ((select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND A.ERROR_CODE = B.ERROR_CODE ) order by a.pod_id desc)
select t1.*
from IMPORT_CTE t1
where t1.insert_date =(select max(t2.insert_date)
from IMPORT_CTE t2
where t2.POD_ID =t1.POD_ID)
WITH IMPORT_CTE1
AS ((select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND A.ERROR_CODE = B.ERROR_CODE ) order by a.pod_id desc)
select t1.insert_date
from IMPORT_CTE1 t1
where t1.insert_date =(select min(t2.insert_date)
from IMPORT_CTE1 t2
where t2.POD_ID =t1.POD_ID)
You've got an extra set of parentheses in each of your queries. The first one should apparently be:
WITH IMPORT_CTE AS
(select A.*
FROM IMPORT_REGISTRY_ERROR_LOG_1 A
INNER JOIN (select distinct POD_ID,CONFLICTED_POD_ID,ERROR_CODE
FROM IMPORT_REGISTRY_ERROR_LOG_1
GROUP BY POD_ID,CONFLICTED_POD_ID,ERROR_CODE
HAVING COUNT(*) > 1) B
on A.POD_ID = B.POD_ID AND
A.CONFLICTED_POD_ID = B.CONFLICTED_POD_ID AND
A.ERROR_CODE = B.ERROR_CODE
order by a.pod_id desc)
select t1.*
from IMPORT_CTE t1
where t1.insert_date = (select max(t2.insert_date)
from IMPORT_CTE t2
where t2.POD_ID = t1.POD_ID)
The second one has a similar problem.
Best of luck.