SQL Server Insert Statement Hangs - sql

Really hoping somebody can offer some advice here. I have a SQL Statement with the following structure:
SELECT <Columns> FROM (SELECT <More columns> FROM (SELECT <AllColumns> FROM View))
Some of the steps might seem unneeded but there is a reason for all of them
The view contains data that is automatically updated each time our import processes run. It contains a rather large query that gathers data from several tables.
From that view our clients can build their own queries in order to create SSAS databases for reporting purposes, hence the second query. Some additional logic like friendly names are also applied here.
Sometimes our clients would like to inspect the data up close, and bringing back a 2GB query over a web application is rarely a good idea. So we have build a facility where the clients can select the data they would like to return from the main query, hence the outer query.
Here is an example query:
SELECT (ColA, ColB, ColC)
FROM (SELECT ColA, ColB, ColC, ColD, ColE, ColF
FROM (Select * FROM FullView))
All of this works correctly but in one specific case there is a problem. In order to make the data retrieval as fast as possible we create a summary table in the database containing the results of the middle query. However, for one of our queries the summary table refuses to build. The queries can successfully create the table with the correct columns but the data will never get populated, the SQL Server statement simply hangs in the air.
I have tried the following:
Originally the statement that creates the summary table was a SELECT INTO statement. It worked for all the queries except the one in question.
Thinking that for some obscure reason resources might not get released I split the statement into a SELECT INTO statement with a WHERE clause of 1=2 (allowing the table to be created) and an INSERT INTO SELECT clause which will create the data. The SELECT INTO statement runs perfectly, the INSERT INTO SELECT clause does nothing.
However, if I were to run the SELECT part of the INSERT INTO clause the query executes in under a minute, which is acceptable as that is how long the original view executes. But if I add the INSERT INTO statement at the front without changing any part of the SELECT statement the query hangs. Maybe it executes somewhere down the line but a query that returns less data going from a minute to several hours might irritate some people.
I have looked at the sp_who2 results and there are no blocks in the system.
Does anybody have any advice or another place I can look for the error?
Thanks!

Related

Oracle is dropping my table before select statement finishes

At work we have a large Oracle SQL query designed to output two select statements based off of analysis and table combining in prior scripts. At the end of these select statements we truncate the temp tables that were created. My issue is that the tables are getting truncated before the select statement has time to run, resulting in 0 output for both queries and empty tables that now need the whole process to be run over again to populate the tables correctly. This is something I'm trying to help automate but I'm stuck on how to get Oracle to wait for the select statement to finish processing before triggering the truncate. Very simply it looks like:
Select * from temp;
Truncate Table temp;
commit;
TRUNCATE is a DDL sentence in Oracle which means it can modify the structure of tables and databases, instead of using TRUNCATE why don't you try to change it for a simple DELETE which is a simple DML sentence in Oracle that just change the data.
What you describe can only ne the case if the 2 select statements (one followed by a truncate) are running in separate sessions. Run in the same session and the problem would be solved although you may lose out on a performance benefit of runnng them in parallel.

Is there any way to safely run SELECT INTO?

I have a script that runs a SELECT INTO into a table. To my knowledge, there are no other procedures that might be concurrently referencing/modifying this table. Once in awhile, however, I get the following error:
Schema changed after the target table was created. Rerun the Select
Into query.
What can cause this error and how do I avoid it?
I did some googling, and this link suggests that SELECT INTO cannot be used safely without some crazy try-catch-retry logic. Is this really the case?
I'm using SQLServer 2012.
Unless you really don't know the fields and data types in advance, I'd recommend first creating the table, then adding the data with an Insert statement. In your link, David Moutray suggests the same thing, here's his example code verbatim:
CREATE TABLE #TempTableY (ParticipantID INT NOT NULL);
INSERT #TempTableY (ParticipantID)
SELECT ParticipantID
FROM TableX;

Debugging sub-queries in TSQL Stored Procedure

How do I debug a complex query with multiple nested sub-queries in SQL Server 2005?
I'm debugging a stored procedure and trigger in Visual Studio 2005. I'd like to be able to see what the results of these sub-queries are, as I feel that this is where the bug is coming from. An example query (slightly redacted) is below:
UPDATE
foo
SET
DateUpdated = ( SELECT TOP 1 inserted.DateUpdated FROM inserted )
...
FROM
tblEP ep
JOIN tblED ed ON ep.EnrollmentID = ed.EnrollmentID
WHERE
ProgramPhaseID = ( SELECT ...)
Visual Studio doesn't seem to offer a way for me to Watch the result of the sub query. Also, if I use a temporary table to store the results (temporary tables are used elsewhere also) I can't view the values stored in that table.
Is there anyway that I can add a watch or in some other way view these sub-queries? I would love it if there was some way to "Step Into" the query itself, but I imagine that wouldn't be possible.
Ok first I would be leary of using subqueries in a trigger. Triggers should be as fast as possible, so get rid of any correlated subqueries which might run row by row instead of in a set-based fashion. Rewrite to joins. If you only want to update records based on what was in the inserted table, then join to it. Also join to the table you are updating. Exactly what are you trying to accomplish with this trigger? It might be easier to give advice if we understood the business rule you are trying to implement.
To debug a trigger this is what I do.
I write a script to:
Do the actual insert to the table
without the trigger on on it
Create a temp table named #inserted
(and/or one named #deleted)
Populate the table as I would expect
the inserted table in the trigger to
be populated from the insert you do.
Add the trigger code (minus the
create or alter trigger parts)
substituting #inserted every time I
reference inserted. (if you plan to
run multiple times until you are
ready to use it in a trigger throw
it in an explicit transaction and
rollback after checking your
results.
Add a query to check the table(s)
you are changing with the trigger for
the values you wanted to change.
Now if you need to add debug
statements to see what is happening
between steps, you can do so.
Run making changes until you get the
results you want.
Once you have the query working as
you expect it to, it is easy to take
the # signs off inserted and use it
to create the body of the trigger.
This is what I usually do in this type of scenerio:
Print out the exact sqls getting generated by each subquery
Then run each of then in the Management Studio as suggested above.
You should check if different parts are giving you the right data you expect.

SQL: How to copy a row in the same table updating one of the fields WITHOUT listing all fields

Hello
I searched for an answer to this question but didn't find any here.
I'm using Access 2010.
Basically, I've got a table with reports, and reports have a revision number.
I found an answer about how to copy fields and update only one of them, but it looks somewhat like this:
INSERT INTO reports (fieldA, fieldB, fieldC, revision, fieldD, fieldE)
SELECT fieldA, fieldB, fieldC, 2, fieldD, fieldE
FROM reports
WHERE <somecondition to select which report to copy>
Thing is I have a load of fields, so I'd like something that would look more like this:
INSERT INTO reports
SELECT *, revision=2
FROM reports
WHERE <somecondition to select which report to copy>
I know that code is incorrect; it's just to describe what I would like. As in, a way to not have a huge SQL line listing all the fields, but only the one I want to change.
(I want to keep a copy of previous revisions in the same table)
Thanks in advance to whoever can help :)
I'm pretty sure you can't do this in MS Access or indeed any other flavor of SQL. What you can do, as you probably already know, is use a stored procedure (called a Stored Query in Access) which takes your revision number and the id of the report to copy (or some other WHERE conditions) as arguments. This way, you still have to specify all the fields, but you do it only once and in your database instead of in your code. An example is here:
http://www.stardeveloper.com/articles/display.html?article=2001050101&page=1
HTH!
I found an interesting alternative in this question, using a temporary table
SQL clone record with a unique index
DROP TABLE #tmp_MyTable
SELECT * INTO #tmp_MyTable
FROM MyTable
WHERE MyIndentID = 165
ALTER TABLE #tmp_MyTable
DROP Column MyIndentID
INSERT INTO MyTable
SELECT *
FROM #tmp_MyTable
I can do the same, dropping the primary key and updating the revision, then copying it back to my table.
Not the solution I'm looking for, but an alternative way in the meantime.
EDIT:
Tried this solution without success:
VBA tells me something along the lines of "fields with multiple values are not allowed with SELECT INTO instructions (runtime error 3838)"
I have both an OLE field and an attachment field, which I suspect to be the cause of the error. But I need to keep them... :/

How can remove lock from table in SQL Server 2005?

I am using the Function in stored procedure , procedure contain transaction and update the table and insert values in the same table , while the function is call in procedure is also fetch data from same table.
i get the procedure is hang with function.
Can have any solution for the same?
If I'm hearing you right, you're talking about an insert BLOCKING ITSELF, not two separate queries blocking each other.
We had a similar problem, an SSIS package was trying to insert a bunch of data into a table, but was trying to make sure those rows didn't already exist. The existing code was something like (vastly simplified):
INSERT INTO bigtable
SELECT customerid, productid, ...
FROM rawtable
WHERE NOT EXISTS (SELECT CustomerID, ProductID From bigtable)
AND ... (other conditions)
This ended up blocking itself because the select on the WHERE NOT EXISTS was preventing the INSERT from occurring.
We considered a few different options, I'll let you decide which approach works for you:
Change the transaction isolation level (see this MSDN article). Our SSIS package was defaulted to SERIALIZABLE, which is the most restrictive. (note, be aware of issues with READ UNCOMMITTED or NOLOCK before you choose this option)
Create a UNIQUE index with IGNORE_DUP_KEY = ON. This means we can insert ALL rows (and remove the "WHERE NOT IN" clause altogether). Duplicates will be rejected, but the batch won't fail completely, and all other valid rows will still insert.
Change your query logic to do something like put all candidate rows into a temp table, then delete all rows that are already in the destination, then insert the rest.
In our case, we already had the data in a temp table, so we simply deleted the rows we didn't want inserted, and did a simple insert on the rest.
This can be difficult to diagnose. Microsoft has provided some information here:
INF: Understanding and resolving SQL Server blocking problems
A brute force way to kill the connection(s) causing the lock is documented here:
http://shujaatsiddiqi.blogspot.com/2009/01/killing-sql-server-process-with-x-lock.html
Some more Microsoft info here: http://support.microsoft.com/kb/323630
How big is the table? Do you have problem if you call the procedure from separate windows? Maybe the problem is related to the amount of data the procedure is working with and lack of indexes.