I have an Oracle database in one server and SQL Server database in another server. I did a count query on the Oracle database locally which returns certain amount of records. However, I was given different record count when I do the same query from the SQL Server.
Below is the Oracle query statement;
select count(*) as TOTALDATA
from
(
select b.name,b.prprty,b.result
from thedatabase.ip_smpl a, thedatabase.ip_tst_rslt b
where a.name = b.name
and a.smpl_dt_tm < to_date(to_char(sysdate,'dd/mm/yyyy')||' 00:00','dd/mm/yyyy hh24:mi')
and a.smpl_dt_tm > to_date(to_char(sysdate-30,'dd/mm/yyyy')||' 00:00','dd/mm/yyyy hh24:mi')
and b.result is not null
and b.name not like 'T%')
Meanwhile, here is the equivalent SQL Server query statement;
SELECT COUNT(*) AS TOTALDATA
FROM
(
SELECT b.NAME, b.PRPRTY, b.RESULT
FROM [LinkedServer]..[thedatabase].[IP_SMPL] a, [LinkedServer]..[thedatabase].[IP_TST_RSLT] b
WHERE a.NAME = b.NAME
AND a.SMPL_DT_TM < CAST(CONVERT(varchar, GETDATE(), 23) + ' 00:00' AS DATETIME)
AND a.SMPL_DT_TM > CAST(CONVERT(varchar, GETDATE() - 30, 23) + ' 00:00' AS DATETIME)
AND b.RESULT IS NOT NULL
AND b.NAME NOT LIKE 'T%') AS D
The former query returns 18263 rows of record while the latter 17849.
Why the different? Perhaps the SQL statement is not literally translated to the same as Oracle statement?
Note that I get same record count if I ran each query minus two last statements.
Related
I want to execute DELETE instruction before the end of my procedure. First I get some data in my CURSOR. On the loop of this CURSOR, for each record of my CURSOR I concatenate id values in variable named "final_list". At the end of the loop I would like to execute DELETE instruction like this : DELETE FROM my_table where my_field IN final_list. But not working.
create or replace PROCEDURE TEST_PURGE is
CURSOR clients IS SELECT DISTINCT client_id
FROM client
WHERE client_description LIKE 'Test%';
client clients%ROWTYPE;
id_log client.client_id%type;
final_list VARCHAR(100);
BEGIN
final_list:='(';
OPEN clients;
LOOP
FETCH clients INTO client;
EXIT WHEN clients%notfound;
SELECT log_id INTO id_log
FROM (SELECT log_id
FROM log
WHERE log_client_id = client.client_id
AND client_description LIKE 'Test%'
ORDER BY log_date DESC)
WHERE ROWNUM < 2;
final_list:=concat(final_list, id_log || ',');
END LOOP;
CLOSE clients;
final_list:=SUBSTR(final_list, 0, LENGTH(final_list) - 1);
final_list:=concat(final_list, ')');
DBMS_OUTPUT.PUT_LINE('Id list: ' || final_list);
DELETE FROM contrh_client_log WHERE contrh_client_log_id IN final_list;
COMMIT;
END TEST_PURGE;
DELETE instruction not working but no error message. When I execute the same DELETE instruction in classic SQL sheet with value of "final_list" variable, it's work.
Does anyone have an idea ?
Yes: the best way of doing this is not by looping through a cursor, running a select statement and then a delete statement; instead, you can do it all in a single delete statement, such as:
DELETE FROM contrh_client_log
WHERE contrh_client_log_id IN (SELECT log_id
FROM (SELECT l.log_client_id,
l.log_id,
row_number() OVER (PARTITION BY l.log_client_id ORDER BY log_date DESC) rn
FROM LOG l
INNER JOIN client c ON l.log_client_id = c.client_id
WHERE l.client_description LIKE 'Test%'
AND c.client_description LIKE 'Test%')
WHERE rn = 1);
(N.B. untested.)
You can then put this in a procedure:
CREATE OR REPLACE PROCEDURE test_purge AS
BEGIN
DELETE FROM contrh_client_log
WHERE contrh_client_log_id IN (SELECT log_id
FROM (SELECT l.log_client_id,
l.log_id,
row_number() over(PARTITION BY l.log_client_id ORDER BY log_date DESC) rn
FROM log l
INNER JOIN client c
ON l.log_client_id = c.client_id
WHERE l.client_description LIKE 'Test%'
AND c.client_description LIKE 'Test%')
WHERE rn = 1);
COMMIT;
END;
/
Doing it like this will be
faster,
easier to understand,
easier to debug (you can just run the delete statement on its own outside of the procedure with little or no changes to it)
easier to maintain in the future.
I have a query which is executing perfectly when run from SSMS. But that same query is throwing the error mentioned in the title when executed from my asp.net (ado.net) application.
Here is the query:
select
[computed column]
from
[externaldb].dbo.[table1] t1
where
t1.userid in (select t2.userid
from [synextdbusers] t2
where t2.guid in (select t3.guid
from [mydb].dbo.[users] t3
where t3.guid is not NULL)
and t2.guid is not NULL)
t1.userid and t2.userid are of data type bigint
t2.guid is uniqueidentifier
t3.guid is nvarchar, [externaldb] is an external database and [mydb] is database where given query is executed
[synextdbusers] is synonym to a table on external database
Any explanation is appreciated.
1) I assume that this error is generated during evaluation of following predicate where t2.guid in (select t3.guid ...). According to data type precedence, UNIQUEIDENTIFIER (t2.guid) has higher precedence than NVARCHAR (t3.guid). Because of this reason, SQL Server will execute an implicit conversion from of t3.guid values from NVARCHAR (lower precedence) to UNIQUEIDENTIFIER (higher precedence) which is the same as CONVERT(UNIQUEIDENTIFIER, t3.guid). If t3.guid / NVARCHAR column contain invalid UNIQUEIDENTIFIER values (ex. empty strings) then an error will be raised. Why this query performs totally different on SSMS ? One simple explanation come from execution plan: the execution plans could be different thus:
a) The execution plan associated with query sent from WebApp avoids reading bad NVARCHAR values from t3.guid column.
b) Execution plan associated with query sent from SSMS have a diff. data access path. This time, the XP forces SQL Server to read bad values (invalid UNIQUEIDENTIFIERs) from t3.column.
2) Why there are diff. execution plan for the "same" query ? Two reasons: (2.1) the SET sessions settings are different for WepApp connection compared with settings for SSMS. Diff. settings and/or (2) parameter sniffing. Because of one of these reasons, execution plans are different.
3) Following query return these settings:
SELECT s.session_id, s.program_name, s.login_name, s.nt_domain, s.nt_user_name, s.quoted_identifier, s.ansi_nulls, s.ansi_warnings, s.* -- see other SETttings
FROM sys.dm_exec_sessions s
WHERE s.session_id IN (<WebApp spid>, <SSMS spid>)
4) To check if there are one or more XP for the same SP you could use following query:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT pln.query_plan, ps.*
FROM sys.dm_exec_procedure_stats ps
OUTER APPLY sys.dm_exec_query_plan(ps.plan_handle) pln
WHERE ps.database_id = DB_ID() -- Check DB for current session
AND ps.object_id = OBJECT_ID('dbo.ProcName')
or
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT *
FROM (
SELECT
SUBSTRING(qt.text,qs.statement_start_offset/2 +1,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END -
qs.statement_start_offset
)/2
) AS query_source_code,
qp.query_plan AS query_xplan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
) x
WHERE x.query_source_code LIKE '%select
[computed column]
from
[externaldb].dbo.[table1] t1
where
t1.userid in (select t2.userid
from [synextdbusers] t2
where t2.guid in (select t3.guid
from [mydb].dbo.[users] t3
where t3.guid is not NULL)
and t2.guid is not NULL)%'
5) Quick demo:
USE tempdb
GO
DROP TABLE dbo.InvoiceDetail
DROP TABLE dbo.Invoice
GO
CREATE TABLE dbo.Invoice (ID INT PRIMARY KEY, InvoiceDate DATE)
CREATE TABLE dbo.InvoiceDetail(ID INT PRIMARY KEY, InvoiceID INT REFERENCES dbo.Invoice(ID), Qty INT, UnitPrice INT, ProductID NVARCHAR(36))
GO
CREATE INDEX OX_InvoiceDetail_InvoiceID_#_ProductID
ON dbo.InvoiceDetail (InvoiceID)
INCLUDE (ProductID)
INSERT dbo.Invoice VALUES
(101, '2016-01-01'),
(102, '2016-02-02'),
(103, '2016-03-03')
GO
INSERT dbo.InvoiceDetail (ID, InvoiceID, Qty, UnitPrice, ProductID)
VALUES
(1, 101, 11, 10, ''),
(2, 102, 22, 20, '00000000-0000-0000-0000-000000000000'),
(3, 103, 33, 30, '00000000-0000-0000-0000-000000000000'),
(4, 103, 44, 40, '00000000-0000-0000-0000-000000000000')
GO
--DELETE dbo.InvoiceDetail WHERE ID = 0
SELECT i.InvoiceDate, id.ProductID
FROM dbo.Invoice i INNER JOIN dbo.InvoiceDetail id ON i.ID = id.InvoiceID
WHERE i.InvoiceDate >= '2016-02-02'
AND id.ProductID = NEWID()
OPTION (FORCE ORDER)
GO
SELECT i.InvoiceDate, id.ProductID
FROM dbo.Invoice i INNER JOIN dbo.InvoiceDetail id ON i.ID = id.InvoiceID
WHERE i.InvoiceDate >= '2016-02-02'
AND id.ProductID = NEWID()
OPTION (HASH JOIN)
GO
Results:
InvoiceDate ProductID
----------- ------------------------------------
(0 row(s) affected)
InvoiceDate ProductID
----------- ------------------------------------
Msg 8169, Level 16, State 2, Line 36
Conversion failed when converting from a character string to uniqueidentifier.
Note: last two queries are similar but because I used those query hints the XP will be also different (in this case).
Create stored procedure
CREATE PROCEDURE dbo.GetBookList
-- Add the parameters for the stored procedure here
AS
BEGIN
create table BookAuthersName
(
BookId int,
Names varchar(255)
);
insert into BookAthersName(BookId,Names)
select
t1.BookId,
stuff((select ', '+a.Name
from BookAuthers t2 join Authers a on t2.AutherId= a.Id where t1.BookId = t2.BookId
for xml path('')),
1,2,'') [Values]
from dbo.BookAuthers t1
group by t1.BookId
create table BookSubjectNames
(
BookTypeId int,
Names varchar(255)
);
insert into BookSubjectNames(BookTypeId,Names)
select
t1.BookTypeId,
stuff((select ', '+a.Name
from BookTypeSubjects t2 join Subjects a on t2.SubjectId= a.Id where t1.BookTypeId = t2.BookTypeId
for xml path('')),
1,2,'') [Values]
from dbo.BookTypeSubjects t1
group by t1.BookTypeId
SELECT dbo.BooksType.Name, dbo.BooksType.BuyingDate AS [Buying Date], dbo.Publishers.Name AS [Publisher Name], dbo.Inventory.TotalBooks AS [Total Books],
dbo.Inventory.TotalIssuedBooks AS [Total Issued Books], ban.Names as [Auther Names] ,bsn.Names as [Subject Names]
FROM dbo.BooksType INNER JOIN dbo.Inventory
ON dbo.BooksType.Id = dbo.Inventory.BookTypeId
INNER JOIN dbo.Publishers ON dbo.BooksType.PublisherId = dbo.Publishers.Id
inner join BookAuthersName ban on dbo.BooksType.Id = ban .BookId
inner join BookSubjectNames bsn on dbo.BooksType.Id = bsn .BookTypeId
drop table BookAuthersName
drop table BookSubjectNames
END
It gives error when executing through a .net website. Error is
The default schema does not exist. error when executing stored
procedure.
Gone through some solutions but none seems to help
I am using Integrated Security=True in webconfig connection string
First thing you must get schema name with query
select schema_name()
If the schema name is null you must try set default name with query
ALTER USER [dbo.database_name] WITH DEFAULT_SCHEMA = [dbo];
I am new to oracle database.
Can someone give me an example of the steps for how to see the last statements executed on the Oracle database 11g r2?
You can use the below query to get the last sql executed based on last sql which was active in database
select ltrim(sq.sql_text)
from v$sql sq, v$session se, v$open_cursor oc
where sq.sql_id = oc.sql_id
and se.saddr = oc.saddr
and se.sid = oc.sid
and se.audsid = SYS_CONTEXT('userenv', 'sessionid')
order by oc.LAST_SQL_ACTIVE_TIME desc;
You can also use the below to find the last query executed in your session.
SELECT (SELECT t2.sql_fulltext
FROM v$sql t2
WHERE t1.prev_sql_id = t2.sql_id
AND t1.prev_child_number = t2.child_number) sql_fulltext
FROM v$session t1
WHERE t1.audsid = Sys_context('userenv', 'sessionid');
You can use the below query:
SELECT program_id, program_line#, sql_text
FROM V$SQL VS , ALL_USERS AU
WHERE (executions >= 1)
AND (parsing_user_id != 0)
AND (AU.user_id(+) = VS.parsing_user_id)
AND UPPER(AU.USERNAME) IN (UPPER('YourUser'))
ORDER BY last_active_time DESC;
if you need to know the statements of an PL/SQL object were executed then use or join with
select *
from dba_objects
where object_id = program_id
Find all sql where sql is like ....
select h.sample_time
, u.username
, h.machine
, s.sql_text
, h.*
from dba_hist_active_sess_history h
inner join v$sql s
on s.sql_id = h.sql_id
left outer join dba_users u
on u.user_id = h.user_id
where s.sql_text like 'DELETE%'
order by h.sample_time desc;
You need to be connected as sysdba user for this sql
A couple of hints:
In SQLplus, type a semicolon+ to see, and slash to execute again
In SQLdeveloper, use F8
If you mean see other users' statements then it's not possible by default.
You can configure AUDIT.
You can see some SQL statements in SELECT * FROM V$SQLAREA;
Connect as SYS user and execute the following query
select sql_text from v$sql where first_load_time=(select max(first_load_time) from v$sql) ;
select sq.PARSING_SCHEMA_NAME, sq.LAST_LOAD_TIME, sq.ELAPSED_TIME, sq.ROWS_PROCESSED, ltrim(sq.sql_text)
from v$sql sq, v$session se
where sq.PARSING_SCHEMA_NAME = 'YOUR_SCHEMA'
order by sq.LAST_LOAD_TIME desc;
I currently have an issue with SQL Server which I can't figure out.
The error is:
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations
SQL:
DECLARE #IdUser INT
Select
#IdUser = Id,
Username,
(Select Count(*) From GagsLikes where Userid = #IdUser And Good = 1) as GagLikes,
(Select Count(*) From GagsViews where UserID = #IdUser),
(Select Count(*) From Gags Where UserID = #IdUser) as GagViews
From
Users
Order by
GagLikes, GagViews
Thanks in advance!
You may not use that variable as you do it try this:
Select
U.Id,
U.Username,
(Select Count(*) From GagsLikes where Userid = U.Id And Good = 1) as GagLikes,
(Select Count(*) From GagsViews where UserID = U.Id),
(Select Count(*) From Gags Where UserID = U.Id) as GagViews
From
Users AS U
Order by
GagLikes, GagViews
your table might return more then one rows . make sure that your table return only one row otherwise it can
t store multiple id's in to one int variable .