November 6, 2006 at 9:16 am
Here's the question in a nutshell:
I have a User Defined Function, that takes a TEXT data type and parses through it to find a certain string and returns a VARCHAR(12) portion of the string. It works fine when I call it and explicitly pass it the text string (from Query Analyzer), but when I use it in a select statement it does not work.
It contains a WHILE loop, so I'm thinking that might be the problem. I have debugged this thing every which way I can think of and can't get it.
Example:
1. This works: SELECT JobNumber, MFJBS.dbo.GetQuoteNumberFromUserText('\par C06D3102-06D3102 \par QUOTATION NO.: 53040-1Q-4 \par REF: 880780 \par PAINT') FROM JobMaster WHERE JobNumber = '06D3104'
It returns: 06D3104 | 53040-1Q-4
2. This doesn't work: SELECT JobNumber, MFJBS.dbo.GetQuoteNumberFromUserText(UserText) FROM JobMaster WHERE JobNumber = '06D3104'
It returns: 06D3104 | 53040-1Q-4 \
It doesn't strip off the last two characters ' \'.
I can post the SQL for the UDF if you need me to. Just wanted to make sure there wasn't anything glaringly wrong with the way I'm calling it. I have full permissions and am using SQL Server 2000.
Thanks,
Jim
PS. I have even tried changing the input var type to varchar(255) but the same results.
November 6, 2006 at 9:26 am
If the udf returns rows, then you cannot use it like this in 2000. In 2005 you could use the cross apply operator but there's no workaround in 2000 other than rethinking the process. And I can't do that for you unless I have more info on what you are trying to do!
November 6, 2006 at 9:38 am
It's a scalar function. Here is the sql:
CREATE FUNCTION GetQuoteNumberFromUserText
(@UserText TEXT)
RETURNS VARCHAR(12)
AS
BEGIN
DECLARE @TempUserText VARCHAR(255)
DECLARE @Result VARCHAR(12)
DECLARE @Var CHAR(1)
DECLARE @Counter TINYINT
IF @UserText IS NULL
SET @Result = ''
ELSE
BEGIN
SET @Var = ''
--Check to see if the word QUOTATION is found:
SET @Counter = CHARINDEX('QUOTATION', @UserText) + 16
IF @Counter > 0
--If it is found, then start processing:
BEGIN
--Note that the longest string we expect is 12 chars (this could be changed):
SET @Result = SUBSTRING(@UserText, @Counter, 12)
--If the first 5 chars are not numeric, return an empty string:
IF ISNUMERIC(SUBSTRING(@Result, 1, 5)) = 0
SET @Result = ''
ELSE
BEGIN
--Set the @Counter variable:
SET @Counter = 6
--Get the 6th character:
SET @Var = SUBSTRING(@Result, @Counter, 1)
--Continue adding characters until you hit a space:
WHILE @Var <> ' '
BEGIN
SET @Counter = @Counter + 1
SET @Var = SUBSTRING(@Result, @Counter, 1)
END
SET @Result = SUBSTRING(@Result, 1, @Counter - 1)
END
END
ELSE
SET @Result = ''
END
RETURN @Result
END
-Jim
November 6, 2006 at 9:41 am
What error are you getting?
November 6, 2006 at 9:45 am
I'm not getting an error, just not the expected results. When I run the function sending it a text string it works. When I run it and pass it the column value (equivalent to the text string I just used) it doesn't work. See the above examples in the previous post.
Thanks-
November 6, 2006 at 2:46 pm
Run this:
SELECT JobNumber, UserText, MFJBS.dbo.GetQuoteNumberFromUserText(UserText) FROM JobMaster WHERE JobNumber = '06D3104'
and see what exactly you function does not handle.
Your UserText must not be the same as the test string you paste in QA.
_____________
Code for TallyGenerator
November 6, 2006 at 2:51 pm
That's what I'm thinking. When I copy and paste it, it must change a CR or LF to a space.
Jim
November 6, 2006 at 3:01 pm
Set in QA "Results to Text" and copy-paste from there.
_____________
Code for TallyGenerator
November 6, 2006 at 3:06 pm
Sure enough - they show up as new lines!
Thanks.
November 6, 2006 at 3:34 pm
And your function is quite bad.
I definitely would not use it.
For example:
SET @Counter = CHARINDEX('QUOTATION', @UserText) + 16
IF @Counter > 0
...
Can you provide an example when @Counter gonna be <= 0?
_____________
Code for TallyGenerator
November 6, 2006 at 5:03 pm
Yes, if the word 'QUOTATION' is not found, this is common.
November 6, 2006 at 5:24 pm
And?
If the word 'QUOTATION' is not found, then @Counter = ?
Check your calculations.
Another issue - CHARINDEX does not work with TEXT. It implicitly converts it into VARCHAR(8000).
Continue?
_____________
Code for TallyGenerator
November 6, 2006 at 7:29 pm
I don't understand your response. If the word 'QUOTATION' is not found then @Counter = 0.
The answer to my original problem, as it turns out, was because I was not testing for the right characters. I was testing for a space, but the string contained Carriage Returns. This is what caused the discrepancy when executing the function with a text string I pasted in and the actual column data. When I pasted the column data in, it converted the CR's to spaces. Anyways, here is the new code, which works.
Thanks for your help! Jim
ALTER FUNCTION GetQuoteNumberFromUserText
(@UserText TEXT)
RETURNS VARCHAR(12)
AS
BEGIN
DECLARE @Result VARCHAR(12)
DECLARE @Counter SMALLINT
DECLARE @TestChar CHAR(1)
DECLARE @Found BIT
SET @Result = ''
SET @Found = 0
IF @UserText IS NOT NULL
BEGIN
--Check to see if the word QUOTATION is found:
SET @Counter = CHARINDEX('QUOTATION', @UserText) + 16
IF @Counter > 0
--If it is found, then start processing:
BEGIN
--Note that the longest string we are getting is 12 chars (this could be changed):
SET @Result = SUBSTRING(@UserText, @Counter, 12)
--If the first 5 chars are numeric, then it is a valid quote number
--and we can get the whole number:
IF ISNUMERIC(LEFT(@Result, 5)) = 1
BEGIN
SET @Counter = 6
SET @TestChar = SUBSTRING(@Result, @Counter, 1)
WHILE @Found = 0
BEGIN
--If the character is a tab, CR, LF, or space, then we have gotten
--to the end of the quote number and can break out of the loop
IF ASCII(@TestChar) IN (10, 13, 9, 32)
SET @Found = 1
SET @Counter = @Counter + 1
SET @TestChar = SUBSTRING(@Result, @Counter, 1)
END
SET @Result = LEFT(@Result, @Counter - 1)
END
ELSE
SET @Result = ''
END
END
RETURN @Result
END
November 7, 2006 at 12:19 am
Have you looked at your code???
SET @Counter = CHARINDEX('QUOTATION', @UserText) + 16
If there is no word 'QUOTATION' then CHARINDEX = 0, @Counter = 0 + 16 = 16
What dom't you understand here?
Another issue into your collection:
ISNUMERIC('123D4') = 1, ISNUMERIC('12E34') = 1
Is it what are looking for?
_____________
Code for TallyGenerator
November 7, 2006 at 6:45 am
To reply to the isnumeric problem :
IF EXISTS (SELECT * FROM dbo.SysObjects WHERE XType = 'FN' AND Name = 'fnIsAllNumbers')
DROP FUNCTION dbo.fnIsAllNumbers
GO
CREATE FUNCTION dbo.fnIsAllNumbers (@Str AS varchar(8000))
RETURNS INT
AS
BEGIN
RETURN (SELECT CASE WHEN @STR NOT LIKE '%[^0-9]%' THEN 1 ELSE 0 END)
END
GO
SELECT dbo.fnIsAllNumbers('12.94')
--0
SELECT dbo.fnIsAllNumbers('12E94')
--0
SELECT dbo.fnIsAllNumbers('0x234')
--0
SELECT dbo.fnIsAllNumbers('0123456789')
--1
Viewing 15 posts - 1 through 15 (of 17 total)
You must be logged in to reply to this topic. Login to reply