I have weird problem with my sql azure database on the live server. The MVC controller is returning an errors as "The wait operation timed out" and Sqlexpection (0x80131904): Timeout expired".
This is happening particularly on a single a sql stored procedure. The program is that if run the stored procedure with same parameter against the database using SMSS 2012 it runs fine and returns returns in less 2 seconds.
This lets me that there is nothing wrong with my stored procedure.
I am calling the stored procedure as below.
List<FileFolderItem> folders = new List<FileFolderItem>();
using (DFModel db = new DFModel())
{
folders.AddRange(
db.GetFolderStructure(companyId, (clientid ?? companyId), folderId, currentUser.df_userId).Select(x => new FileFolderItem
{
Name = x.name,
Id = x.id,
Flags = "USER_FOLDER",
TotalFiles = x.Files.Value,
TotalSize = x.Size.Value
}).ToList<FileFolderItem>()
);
return folders;
}
I have done further test by taking a backup of the database and restore on the same sql azure instance as seperate new database and pointing my application connection to the backup db and the application works.
I don't understand how should I troubleshoot this problem, there no way to restart the sql azure instance.
Any help will be highly appreciated.
Thanks
Edited on 13/03/2013
After further investigation - the problem seems to be with Table-Valued function (getfilesbyclaims) called from sub-procedure GetFolderTotalSize. Is this functions are not fully supported. The strange thing is that the application did go live about 4 weeks ago and this problem suddenly started yesterday # 4pm.
CREATE PROCEDURE [dbo].[GetFolderStructure]
#companyid int,
#clientid int,
#folderid int,
#personid int
AS
SELECT
fd.id,
fd.name,
dbo.getfoldertotalfiles(#companyid, #clientid, fd.id, #personid) AS Files,
--0 as Files,
dbo.getfoldertotalsize(#companyid, #clientid, fd.id, #personid) as Size
--0 as Size
FROM folders fd
WHERE fd.companyid = #companyid
AND fd.root_id = #folderid
AND (fd.hidden IS NULL OR fd.hidden = 0)
Sub-Procedure - GetFolderTotalFiles
ALTER FUNCTION [dbo].[GetFolderTotalSize]
(
#companyid int,
#clientid int,
#folderid int,
#personid int
)
RETURNS INT
AS
BEGIN
DECLARE #size int;
DECLARE #tblFiles TABLE (
Id uniqueidentifier not null,
CompanyId int,
folderid int,
contentLength bigint
);
INSERT INTO #tblFiles(id, companyid, folderid, contentlength)
SELECT * FROM dbo.getfilesbyclaims(#clientid, #personid);
WITH Folder_CTE as (
select fs.* FROM folders AS fs
where companyid = #companyid
AND id = #folderid
UNION ALL
SELECT f.* FROM folders f
INNER JOIN Folder_CTE fcte ON fcte.id = f.root_id)
SELECT #size = ISNULL(SUM(f.contentlength), 0) FROM folder_cte fd
INNER JOIN #tblFiles f ON f.folderid = fd.id
where f.companyid = #clientid
return #size;
END
GO
Related
Already checked this post: SSIS and sending query with date to Oracle
And I'm using variable query per below thread
SSIS - Using parameters in Oracle Query using Attunity Oracle Datasource
Tool used: VS-2019
Data flow: MS Oracle Source (for VS-2019)
My source is Snowflake cloud. I'm successfully able to get the max date from table and store in Object type variable (named:- #var_Snowflake_Table_maxDate). Then I use a script task to convert the value to string type.
Code for script task is:
public void Main()
{
OleDbDataAdapter A = new OleDbDataAdapter(); //using System.Data.OleDb; ADDED above in NAMESPACES
System.Data.DataTable dt = new System.Data.DataTable();
A.Fill(dt, Dts.Variables["User::var_Snowflake_Table_maxDate"].Value);
foreach (DataRow row in dt.Rows)
{
object[] array = row.ItemArray;
Dts.Variables["User::var_CreateDate"].Value = array[0].ToString();
}
Dts.TaskResult = (int)ScriptResults.Success;
}
This sets my param of #var_CreateDate String type correctly. I tried this on local machine and was able to pass the value to a native instance of sql-server(yes NOT oracle). Just to test my parameters from script task works.
Finally: I'm using VS-2019's MS Oracle Source to pass the value into Oracle cloud server. Sample query's I have tried
"select * from Table where rownum <= 5 and NVL(CREATE_DATE,UPDATE_DATE) = " +"'05-09-2020'"
::::evals to::::
select * from relate.awd_acct_activity where rownum <= 5 and NVL(CREATE_DATE,UPDATE_DATE) = '2020-05-09'
and this works. But value is hard coded.
Try 2:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = " +"'#[User::var_CreateDate]'"
Try 3:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" +"'#[User::var_CreateDate]'"+")"
Try 4:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" +"'#[User::var_CreateDate]'"+",'YYYY-MM-DD')"
None of try 2 through 4 eval correctly. Can I have some guidance into how to pass this parameter to Oracle cloud.
Thanks.
I'm assuming you're trying to figure out the syntax for a variable, that would hold the query text. You can try something like this:
"select * from table where rownum <= 50 and
NVL(CREATE_DATE,UPDATE_DATE) = to_date(" + "'" + #[User::var_CreateDate] + "'" + ",'YYYY-MM-DD')"
I'm working on creating a pl/sql function that finds the highest average of students from a list of classes. I have the average computation part working correctly; however, I need to return the results as a table of records and I'm running into the error while attempting to store the results into the record.
My record declaration is as follows
create or replace TYPE studentRec as object (
term varchar2(10),
lineNum number(4),
coTitle varchar2(50),
stuId varchar2(5),
average number);
The error comes when I'm trying to fill the record using a select into statement.
create or replace function highest_avg(stu_id scores.sid%type,
line_no scores.lineno%type)
return stuRecTab
as
stuRec stuRecTab;
average number;
studentRec_t studentRec;
begin
stuRec := stuRecTab();
select avg(points)
into average
from scores, courses
where scores.sid = stu_id
and scores.lineno = line_no
and scores.term = courses.term
and scores.lineno = courses.lineno;
SELECT DISTINCT c.term, c.lineno, cc.ctitle, s.sid, average
INTO studentRec_t
from courses c, class_catalog cc, scores s
where s.sid = stu_id
and s.lineno = line_no
and s.term = c.term
and s.lineno = c.lineno
and c.cno = cc.cno;
stuRec := studentRec_t;
return(stuRec);
end;
I've run it as just a query and I'm getting back what I expect so I'm not sure why this error is popping up. Any help would be greatly appreciated as this is my first time working with pl/sql.
First, you can't SELECT INTO the fields of an object instance variable - you have to create an object instance in your select, then SELECT that INTO your object instance variable. You can't simply assign an instance variable to a collection - you need to put it at an appropriate index. So what you end up with is something like:
create or replace function highest_avg(stu_id scores.sid%type,
line_no scores.lineno%type)
return stuRecTab
as
stuRec stuRecTab;
average number;
studentRec_t studentRec;
begin
stuRec := stuRecTab();
select avg(points)
into average
from scores s
inner join courses c
on c.term = s.term and
c.lineno = s.lineno
where s.sid = stu_id and
s.lineno = line_no;
SELECT studentRec(term, lineno, ctitle, sid, average)
INTO studentRec_t
FROM (SELECT DISTINCT c.term, c.lineno, cc.ctitle, s.sid, average
from scores s
INNER JOIN courses c
ON s.term = c.term and
s.lineno = c.lineno
INNER JOIN class_catalog cc
ON cc.cno = c.cno
where s.sid = stu_id and
s.lineno = line_no);
stuRec(1) := studentRec_t;
return(stuRec);
end;
As no test data was provided I haven't tested this - but at least it compiles at dbfiddle.
Fetching data through a python application from a table throws me this error:
cx_Oracle.DatabaseError: ORA-00942: table or view does not exist. I have verified the schema and table name.
cur = cursor.execute('SELECT * FROM SYS.STUDENT_RECORDS')
However, the application fetches data from the system table.
cur = cursor.execute("SELECT * FROM TAB_STATS$ WHERE ROWNUM <= 10")
Here is the connection string:
dsn_tns = cx_Oracle.makedsn(ip, port, SID)
connection = cx_Oracle.connect(user='username', password='****',dsn=dsn_tns)
I am assuming it has got to do something with the user permission, but not quite getting it right. I don't have much experience with Oracle DB. Any help would be highly appreciated.
#kaushik #krokodilko, your guidance helped me arrive at the following solution:
Created new user and granted privileges.
Changed connection string to use service name instead of SID.(don't know why SID didn't work though)
dsn_tns = cx_Oracle.makedsn(ip, port, service_name=service_name)
cur = cursor.execute("SELECT * FROM user1.STUDENT_PROFILES WHERE ROWNUM <= 10")
We got ~500 of tests which run nightly on an Oracle database.
Before every test we truncate all tables with the following code:
public override void EmptyTables()
{
const string alterConstraints = "begin for i in (select c.* from user_constraints c, user_tables u where c.table_name = u.table_name and c.constraint_type = 'R') LOOP EXECUTE IMMEDIATE 'alter table ' || i.table_name || ' {0} constraint ' || i.constraint_name; end loop; end;";
List<string> commandList = new List<string>();
commandList.Add( string.Format( alterConstraints, "disable" ) );
commandList.AddRange( GetTableNames().Select( tn => string.Format( "truncate table {0}", tn ) ) );
commandList.Add( string.Format( alterConstraints, "enable" ) );
ExecuteNonQuery( commandList );
}
public virtual void ExecuteNonQuery( IList<string> statements )
{
DbTransaction dbTransaction = DbConnection.BeginTransaction();
foreach( string statement in statements )
{
DbCommand dbComand = CreateDbCommand( statement, dbTransaction );
dbComand.CommandTimeout = 60 * 30;
try
{
dbComand.ExecuteNonQuery();
}
catch( Exception exception )
{
HandleExecuteNonQueryException( exception, dbTransaction, statement );
}
finally
{
dbComand.Dispose();
}
}
dbTransaction.Commit();
}
Nearly every night some (~5, random) of these tests fail at ExecuteNonQuery with either ORA-00060 or ORA-04020 deadlock (Statement: alter table SOMETABLE disable constraint FK_SOMEFK => the table and FK and disable/enable is random as well).
I know it could be very tricky to find out the problem, but might anyone out there have an idea :)
Thanks!
I would start with gathering statictics about test failures.
Before each call of EmptyTables method check and log results of the query:
select obj.owner,
obj.object_name,
obj.object_type,
s.sid,
s.serial#,
s.status,
s.osuser,
s.machine
from v$locked_object lo,
v$session s,
dba_objects obj
where s.sid = lo.session_id
and lo.object_id = obj.object_id;
First of all look for objects locked by sessions opened in previous test runs.
Сonsidering "random" nature of failures and repeatability of the situation, I see two suspicious possibilities:
If you run tests using several sessions, for some reason session of previous test does not have enough time to free resources. For the first time you could kill sessions found by the query, until you understand why they are not being closed properly.
If all tests reuse the same session, definetely (as mentioned in the comments) someone else plays with the schema while the tests run. But I think it's not the case, since you made fine isolated schema for test runs only: I hope you create it before start the tests and drop it after them.
To fail fast you may lock each table before DDL operaitons:
LOCK TABLE table_name IN EXCLUSIVE MODE NOWAIT;
I have a an sqlite database with the table test. Several processes are accessing this database from bash. The table has the following fields:
CREATE TABLE mytable (id NUMERIC,
start JULIAN,
finish JULIAN)
I obtain an unique id by:
id=$(sqlite test.db <<EOF
BEGIN EXCLUSIVE;
SELECT id FROM mytable WHERE start IS NULL ORDER BY RANDOM() LIMIT 1;
COMMIT;
EOF
)
My question is, how can update the field start with:
UPDATE mytable set start=julianday('now') where id="SELECTED ID FROM ABOVE";
In the same statement?
Based on the comments that you supplied above, my solution would look something like follows (in perl with a raw DBI connection, also i didn't do a lot of error checking or anything either, something that you should probably do):
my $dbh = DBI->connect(...);
$dbh->do("BEGIN EXCLUSIVE");
my $stm = $dbh->prepare("SELECT id FROM mytable WHERE start IS NULL ORDER BY RANDOM() LIMIT 1");
$stm->execute();
my $row = $stm->fetchrow_hashref();
my $id = undef;
if ( $row ) {
$id = $row->{ID};
my $ustm = $dbh->prepare("UPDATE mytable set start=julianday('now') where id=?");
$ustm->execute($id);
}
$dbh->do("COMMIT");
# Still have the id at this point.