SSMS 2008 R2 Outlining At Incorrect Place - sql-server-2008

I am using SSMS 2008R2 to connect to a SQL 2012 Enterprise database (if that matters). Based on the screenshot below you can see that the outlining that SSMS is adding is in the incorrect place. Any ideas on how to ensure that the outlining works correctly? Also, when an error occurs in the query the line numbers in the error in no way align to the line numbers in the query/file (off by hundreds).
I have blacked out some of the fields but I assure you the query runs fine so the syntax of the select statement is not the issue.

A quick answer is you can DOUBLE CLICK on the ERROR MESSAGE in SSMS and it will take you to the actual error, regardless if the Line # it's stating the error is at matches what you see inside SSMS... usually.
With that being said, here are some things to keep in mind...
BATCH
First, each BATCH will count against your line number. Run the code below. It will error out at line 34, though the error is at 39. The reason is we are taking up 5 lines with the first two batches QUOTED_IDENTIFIER and ANSI_NULLS. If you comment these out, the correct line number will be returned.
SELECT WITH WHERE / JOINS
If your error is somewhere in your WHERE and potentially a JOIN, the line number for the beginning of the statement will be returned. Comment out the first two batches, uncomment the SELECT at the bottom where we divide by 0, and comment out the SET #testing = 'one' at the bottom. You'll notice Line 34 is what will be returned in the Error, which is the start of the statement, but the actual error is on line 37.
ERROR IN SELECT
Apparently the type of error, which I haven't narrowed down--but not Level and State-- affects the line number. I can't tell you why but it's something to keep in mind. In the divide by 0 error, if you double click on the error message it will take you to the SELECT statement versus the actual line number of the error. This is the "usually" clause i mentioned at the top of the post.
Here is a code snippet.
SELECT
1/1,
1/2,
--a.b --Errors at the actual line
1/0 --Errors at the SELECT line number
WHERE
1=1
ERROR_LINE()
You can use ERROR_LINE() to return the error line, but this is going to mimic what you see in the error in SSMS. So if you have multiple batches it will be "incorrect".
WORK AROUND?
Perhaps math... each SELECT as you suggested, depending on the error, can be counted as 1 line. So having a counter of lines in your code (BATCH + 1 for each select) could help you narrow down the error potentially. Or, if it's a procedure, look into sp_helptext
CODE FOR TESTING
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET NOCOUNT ON
SELECT
CASE
WHEN 1=1 THEN 1
ELSE 2
END
DECLARE #Testing int
SET #Testing = 1
IF #Testing = 1
BEGIN
SELECT
'Testing is set to 1'
END
ELSE
BEGIN
SELECT
'Testing is not set to 1'
END
--SELECT
--1
-- WHERE
--1 = #Testing / 0
SET #Testing = 'one'
GO

Related

How to check which row produces and error in SQL

I am using complex UDF on string which has produced and error: Invalid length parameter passed to the LEFT or SUBSTRING function.
Is there a way to check which row produces and error - something like:
select
UDF(arguments)
from tb
where
IsError(UDF(arguments))=TRUE
Is there something like IsError to get such bad records?
Not as far as I know.
Your best bet as I see it would be to do a cursor that can call the UDF for each row, and then you can capture the error per row.
So I'm thinking something like
(pseducode)
DECLARE CURSOR FOR YOUR TABLE
WHILE ##FETCH_STATUS = 0 BEGIN
TRY UDF
CATCH ERROR AND LOG
END
REPORT ALL ERRORS
(this is one of the few times a cursor is good in SQL because you need to handle each row individually)

MySQL Workbench error messages

I'm trying to apply a routine to a database using MYSQL workbench but I'm having a few problems.
In the first image below, you see the mysql I'm using. This mysql has worked for someone else (i.e. the author of the book I'm following), but when I enter it, there's three error warnings (the Xs in the red boxes).
The other two images below show what happens after I hit apply the first time(showing me the SQL to be applied on the database), and then the second time (producing the error message)
Can anyone see how to fix this problem?
Note, the code that's being entered is a formula to calculate distance between two points, but, as said, it's worked for the author of the book I'm using (Larry Ullman's PHP 5)
I think it's to do with your DELIMITER declaration missing.
You need to add:-
DELIMITER $$ on line 1 before your function.
Then remove the space from END $$ so it becomes END$$

Does SQL Server Management Studio (or SQL Server) evaluate *all* expressions?

Here's my configuration:
I have a re-runnable batch script that I use to update my database.
Inside of that batch script, I have code that says the following:
If Table 'A' doesn't exist, then create Table 'A' and insert rows into it.
Later on in that batch script, I create an schemabound indexed view on that table.
And if you didn't already know, indexed views require specific client settings.
Sometimes, when I re-run the script, that is after the table has been created, SQL Server Management Studio evaluates the "insert rows" code, which is protected by the 'If this table doesn't exist' code, and yields the following error:
Msg 1934, Level 16, State 1, Line 15
INSERT failed because the following SET options have incorrect settings: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS, ANSI_PADDING, ARITHABORT'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
Please note: If someone were to try this INSERT statement in a vacuum, I would fully expect SSMS to generate this error.
But not when it's protected by a conditional block.
My Question:
Does the SSMS compiler evaluate all expressions, regardless of whether they will actually be executed?
Yes, it evaluates all of them,take a look at this
declare #i int
select #i =1
if #i = 1
begin
declare #i2 int
set #i2 = 5
end
else
begin
declare #i2 int
set #i2 = 5
end
Msg 134, Level 15, State 1, Line 12
The variable name '#i2' has already been declared. Variable names must be unique within a query batch or stored procedure.
Another example with temp tables is here: What is deferred name resolution and why do you need to care?
your only way out would be to wrap it inside dynamic SQL
Note that most of the settings you mention are connection-level, i.e. in case you set/change them they stay in effect unless you close the connection or explicitly change their value.
Returning to your question. The error you mention looks like runtime error, i.e. the INSERT is actually being executed. It would be better if you could show your script (omitting details, but keeping batches).
Edit: it is not SSMS compiler that evaluates SQL you try to execute - it is SQL Server. What do you meant by 'evaluate'? Is it 'execute'? When you run a batch (which is what actually is being executed by a server), SQL Server first does syntactic analysis and throws error in case it finds any syntactic error, nothing is being executed at this point of time. In case syntax is ok, the server starts executing you batch.
Again, the error you show seems to be runtime - so I guess you'd carefully watch for the conditions and track what happens (or provide us more details about 'sometimes').

SQL Server stored procedure line number issue

I am using SQL Server 2008 Enterprise. I met with issue which says line 9 of stored procedure foo is meeting with dead lock issue. My question is how to find exactly the 9th line of the stored procedure?
My confusion is because of coding format issue, how to locate 9th line correctly.
thanks in advance,
George
A tip I learnt from another answer ...
If you do
sp_helptext procedure_name
SQL will output its 'remembered' version of the create procedure statement, and that is what it gets it line numbers from apparently. If you have SSMS in 'grid output' mode then it will also output the line numbers (as the row numbers of the result set).
NB: in my case it was working from the CREATE PROCEDURE statement plus a bunch of comments above it, so line 1 was about 6 lines above the CREATE PROCEDURE call.
It's the 9th line from the CREATE PROCEDURE statement. A SQL statement is often multiline so "line 9" will refer to the first line of the statement (eg INSERT or UPDATE)
However, if you have comments above the CREATE PROCEDURE or blank lines before it then you can't rely on this... so run ALTER PROC with ALTER PROC as first line in the batch.
The line numbers outputted by sp_helptext are totally different than the line number you see in the error message.
For instance, in my stored procedure error it said the error occured on line number 194 but actually my stored procedure showed only 136 lines when I showed sp_helptext. BTW, I used SQL Server 2008.

MySQL query browser procedure error code -1

I'm having a rather strange problem with MySQL. Trying to create a procedure to update some fields in the database (the code is below).
The problem is with the line that is currently commented. It seems that if no SELECT statements get executed during the procedure MySQL query browser will return an error code of "-1, error executing SQL query".
I tried the same thing in HeidiSQL and the error was "cannot return result set". So I suppose the question is do I always have to select something in the procedure, or is there some other thing I missed.
The query works fine when the comment is removed.
DELIMITER /
DROP PROCEDURE IF EXISTS updateFavourites /
CREATE PROCEDURE updateFavourites(quota INT)
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE artist_id,releases INT;
DECLARE c_artist Cursor FOR
SELECT Artist.id_number,COUNT(Artist.id_number) FROM Artist
JOIN CD ON CD.is_fronted_by = Artist.id_number
GROUP BY Artist.id_number;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET done=1;
IF quota > 0 THEN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
-- SELECT 'Great success';
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;
END /
DELIMITER ;
Here's the sql to create the tables and some data:
DROP TABLE IF EXISTS CD;
DROP TABLE IF EXISTS Artist;
CREATE TABLE Artist (
id_number INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
);
CREATE TABLE CD (
catalog_no INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
is_fronted_by INT UNSIGNED,
rating ENUM ('favourite','top draw','good','so-so','poor','rubbish'),
CONSTRAINT fk_CD_Artist FOREIGN KEY (is_fronted_by) REFERENCES Artist(id_number) ON UPDATE CASCADE
);
INSERT INTO Artist VALUES(11,'Artist 1');
INSERT INTO Artist VALUES(10,'Artist 2');
INSERT INTO CD VALUES (7,11, 'top draw');
INSERT INTO CD VALUES (650,11,'good');
INSERT INTO CD VALUES (651,11,'good');
INSERT INTO CD VALUES (11,10,'favourite');
Query Browser is not for running scripts, just single query.
I tried your code by moving cursor into each query (except DELIMITER) and pressing Ctrl+Enter.
It created that stored procedure without problem. (just refresh schema on the left).
If you wish creating procedure, use menu "Script"->"Create stored procedure/function".
But better forget about QueryBrowser it is not supported at all (and actunally not useful).
If you have decent hardware and plenty resources, try Workbench 5.2 otherwise use SQLyog
Googling around, there are several reports of the same error, but little information to solve the problem. There's even a bug logged at mysql.com but it appears to have been abandoned without being resolved.
There's another StackOverflow question on the same error, but it's also unresolved.
All it means is that there is no result set from the query. Looking at the source code, it appears that sometimes an error status of MYX_SQL_ERROR is set when the query has no result set. Perhaps this is not an appropriate consequence?
I notice that when I use the mysql command-line client, it yields no error for calling a proc that returns no result set.
update: I tried to revive that MySQL bug report, and provide a good test case for them. They changed the bug from "no feedback" to "verified" -- so at least they acknowledge it's a bug in Query Browser:
[11 Dec 9:18] Sveta Smirnova
Bill,
thank you for the feedback. Verified
as described.
Although most likely this only be
fixed when MySQL Query Browser
functionality is part of MySQL
workbench.
I guess the workaround is to ignore the -1 error, or to test your stored procedures in the command-line mysql client, where the error does not occur.
The comment supposes the issue will disappear as the Query Browser functionality becomes part of MySQL Workbench. This is supposed to happen in MySQL Workbench 5.2. I'll download this beta and give it a try.
MySQL Workbench 5.2 is in Beta, but I would assume MySQL engineering can't predict when the Beta will become GA. Those kinds of predictions are hard enough under standard conditions, but there's a lot of extra uncertainty of MySQL's fate due to the unresolved Oracle acquisition.
update: Okay, I have tried MySQL Workbench 5.2.10 beta. I executed a stored procedure like this:
CREATE PROCEDURE FooProc(doquery SMALLINT)
BEGIN
IF doquery THEN
SELECT * FROM Foo;
END IF;
END
When I CALL FooProc(0) the response is no result set, and the status is simply "OK".
When I CALL FooProc(1) the response is the result of SELECT * FROM Foo as expected.
However, there's another bug related to calling procedures. Procedures may have multiple result sets, so it's hard to know when to close the statement when you execute a CALL query. The consequence is that MySQL Workbench 5.2 doesn't close the statement, and if you try to do another query (either CALL or SELECT) it gives you an error:
Commands out of sync; you can't run this command now.
MySQL doesn't support multiple concurrent open queries. So the last one must be closed before you can start a new one. But it isn't closing the CALL query. This bug is also logged at the MySQL site.
The bug about commands out of sync has been resolved. They say it's fixed in MySQL Workbench 5.2.11.
Try putting BEGIN and END blocks around the multiple statements in the IF block as such:
IF quota > 0 THEN
BEGIN
OPEN c_artist;
REPEAT
FETCH c_artist INTO artist_id,releases;
IF NOT done THEN
IF releases >= quota THEN
UPDATE CD SET CD.rating='favourite' WHERE CD.is_fronted_by = artist_id;
END IF;
END IF;
UNTIL done END REPEAT;
CLOSE c_artist;
END;
ELSE
SELECT CONCAT('\'quota\' must be greater than 0.',' Got (',quota,')');
END IF;