Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Perform Logical AND

Author  Topic 

vladimir_grigoro
Yak Posting Veteran

62 Posts

Posted - 2004-01-14 : 12:12:12
Dear All,

I want to ask for the best and fastest solution of the following problem:

Example:
A table X with a column A char(16);
I want to write a stored procedure, which should perform a search in column A as a logical AND.

The column has a values:
Row 1 - 0000000010001000
Row 2 - 1000100011001000
Row 3 - 0000000001000010

I want to find a values, which correspond to a parameter received from the stored procedure: 0000000010001000

The result should be: Row 1,2.

I want to perform a logical AND based on the parameter and the values in the column … the parameter is something as a bit mask.

The search should return all rows, which have “1” at the same position as the parameter.

Thank you in advance.


The Rebel

setbasedisthetruepath
Used SQL Salesman

992 Posts

Posted - 2004-01-14 : 13:07:31
First, you should consider replacing the char(16) with binary(2).

You're askig for a procedure that returns all rows where the (input parameter AND column value) == column value. If you do this w/ a binary column you can write it just as above.

Jonathan
Gaming will never be the same
Go to Top of Page

vladimir_grigoro
Yak Posting Veteran

62 Posts

Posted - 2004-01-14 : 13:29:48
Yes, You are right but this is the existing systme under SQL Server 2000 and I could not change it at the moment.

But thank you anyway your explanation of the problem is better thatn mine:-) But finally is there anyway to solve the problem with the existing situation with column with char(16).

Is there any way to perform anykind of conversion from char916) to binary(2) and then to search based on such received parameter?

quote:
Originally posted by setbasedisthetruepath

First, you should consider replacing the char(16) with binary(2).

You're askig for a procedure that returns all rows where the (input parameter AND column value) == column value. If you do this w/ a binary column you can write it just as above.

Jonathan
Gaming will never be the same



The Rebel
Go to Top of Page

tkizer
Almighty SQL Goddess

38200 Posts

Posted - 2004-01-14 : 13:33:42
CONVERT it to BINARY in the statement.

SELECT CONVERT(BINARY, SomeColumn)
FROM SomeTable

Tara
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 13:34:37
Well...I didn't think (damn it again) about that...

So I wasted my time with a sledge hammer


CREATE TABLE A (A char(16))
GO

INSERT INTO A(A)
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000000011001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000011100010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100111001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000001010001100' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000010001000010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000100001000010'
GO

DECLARE @a char(16), @x int, @y int, @z int, @SQL varchar(8000)
SELECT @a = '0000000010001000', @SQL = 'SELECT * FROM A WHERE', @z = 0, @y = 0
SELECT @x = LEN(REPLACE(@a,'0',''))

WHILE @y < @x
BEGIN
SELECT @z = CHARINDEX('1',@A,@z+1)
SELECT @SQL = @SQL + ' SUBSTRING(A,'+CONVERT(varchar(4),@z)+',1) = '
+ ''''+ '1' + '''' + ' AND'
, @y = @y + 1
END
SELECT @SQL = LEFT(@SQL,LEN(@SQL)-4)
EXEC(@SQL)

DROP TABLE A
GO




I'll go take a look into the other approach...



Brett

8-)
Go to Top of Page

vladimir_grigoro
Yak Posting Veteran

62 Posts

Posted - 2004-01-14 : 14:25:13
Could show me an example how to perform "char to binary" conversion of both values (column and parameter) and then to perform "BOOLEN AND" between them?

quote:
Originally posted by tduggan

CONVERT it to BINARY in the statement.

SELECT CONVERT(BINARY, SomeColumn)
FROM SomeTable

Tara



The Rebel
Go to Top of Page

vladimir_grigoro
Yak Posting Veteran

62 Posts

Posted - 2004-01-14 : 14:27:42
Thanks that's seems very reasonable and good solution of the problem!!!

However Is there any chance to make faster solution based on somekind converstions from char to binary?

quote:
Originally posted by X002548

Well...I didn't think (damn it again) about that...

So I wasted my time with a sledge hammer


CREATE TABLE A (A char(16))
GO

INSERT INTO A(A)
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000000011001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000011100010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100111001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000001010001100' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000010001000010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000100001000010'
GO

DECLARE @a char(16), @x int, @y int, @z int, @SQL varchar(8000)
SELECT @a = '0000000010001000', @SQL = 'SELECT * FROM A WHERE', @z = 0, @y = 0
SELECT @x = LEN(REPLACE(@a,'0',''))

WHILE @y < @x
BEGIN
SELECT @z = CHARINDEX('1',@A,@z+1)
SELECT @SQL = @SQL + ' SUBSTRING(A,'+CONVERT(varchar(4),@z)+',1) = '
+ ''''+ '1' + '''' + ' AND'
, @y = @y + 1
END
SELECT @SQL = LEFT(@SQL,LEN(@SQL)-4)
EXEC(@SQL)

DROP TABLE A
GO




I'll go take a look into the other approach...



Brett

8-)



The Rebel
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 14:51:20
Jonathan/Tara,

Like this? (It doesn't give the correct answer though)

[code]
CREATE TABLE A (A char(16))
GO

INSERT INTO A(A)
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000000011001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000000011100010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100111001000' UNION ALL
SELECT '0000000001000010' UNION ALL
SELECT '0000001010001100' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000010001000010' UNION ALL
SELECT '0000000010001000' UNION ALL
SELECT '1000100011001000' UNION ALL
SELECT '0000100001000010'
GO

DECLARE @a char(16)
SELECT @a = '0000000010001000'
SELECT * FROM A WHERE CONVERT(binary(2),A) = CONVERT(binary(2),@A)

DROP TABLE A
GO



Brett

8-)
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-01-14 : 14:52:38
EDIT -- never mind, misread the question .... i thought you wanted to do an "aggregate AND" of these strings ......

----

you could do something like this:

select min(substring(A,1,1)) + min(substring(A,2,1)) + min(substring(A,3,1)) _+ ....
from yourtable


that just add one "min(substring(A,N,1))" per character position in your char field.

to do a logical OR, use MAX() instead of min.



- Jeff
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 15:07:53
quote:
Originally posted by jsmith8858

EDIT -- never mind, misread the question .... i thought you wanted to do an "aggregate AND" of these strings ......

----

you could do something like this:

select min(substring(A,1,1)) + min(substring(A,2,1)) + min(substring(A,3,1)) _+ ....
from yourtable


that just add one "min(substring(A,N,1))" per character position in your char field.

to do a logical OR, use MAX() instead of min.



- Jeff



OK....my trolley just derailed...huh?



Brett

8-)
Go to Top of Page

setbasedisthetruepath
Used SQL Salesman

992 Posts

Posted - 2004-01-14 : 15:33:54
The CONVERT() won't do a string conversion to binary properly; AFAIK you will need to create an integer representation of the char(16) and then CONVERT().

Jonathan
Gaming will never be the same
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 15:39:35
That just gives an exact match...

SELECT * FROM A WHERE CONVERT(binary(2),CONVERT(bigint,A)) = CONVERT(binary(2),CONVERT(bigint,@A))


What the "==" you're referencing?



Brett

8-)
Go to Top of Page

setbasedisthetruepath
Used SQL Salesman

992 Posts

Posted - 2004-01-14 : 15:45:31
No, no- you will need to actually create the integer representation by doing a manual calculation. SQL Server does not have a built-in function to do it.

SO-
if I had "00100001", as an example, I would need to write a UDF that did its thing and returned 33. THEN you can convert 33 to binary, giving you 0x100001.

Never mind the ==, a typo.

Jonathan
Gaming will never be the same
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 15:54:32
quote:
Originally posted by setbasedisthetruepath

No, no- you will need to actually create the integer representation by doing a manual calculation. SQL Server does not have a built-in function to do it.

SO-
if I had "00100001", as an example, I would need to write a UDF that did its thing and returned 33. THEN you can convert 33 to binary, giving you 0x100001.

Never mind the ==, a typo.

Jonathan
Gaming will never be the same



[dense as a brick wall]
Got it....
[/dense as a brick wall]


Always wondered why there wasn't a ASCII_TO_BIN AND BIN_TO_ASCII function...



Brett

8-)
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-14 : 16:13:03
I alwqys wanted to build that...kinda like a REXX function I used to use...

But that would give equality, no? Or am I still missing the boat?

The original request basically said, if ANY of the rows have a matching 1 in the parameter "mask" the it's a hit....

Or am I mistating...and/or am I still missing you solution Jonathan?



CREATE FUNCTION udf_BIN_TO_ASCII(@a char(16))
RETURNS int
AS
BEGIN
DECLARE @x int, @y bigint
SELECT @x = 1, @y = 0, @a = REVERSE(@a)
WHILE @x < 16
BEGIN
IF SUBSTRING(@a,@x,1) = 1
SELECT @y = @y + POWER(2,@x-1)
SELECT @x = @x + 1
END
RETURN @y
END
GO

SELECT dbo.udf_BIN_TO_ASCII(a) FROM A




Brett

8-)
Go to Top of Page

setbasedisthetruepath
Used SQL Salesman

992 Posts

Posted - 2004-01-14 : 16:22:46
Whoa ... REXX. An OS/2 red-headed stepchild. Be careful who you admit that to .

Well you might consider changing the function name to "BinaryStringToInt" or something like that, the current name sounds like it will return a varchar.

So the procedure might look something like:

create procedure Something
@parm binary(2)
as
select ...
from {table} a
where (@parm & udf_BIN_TO_ASCII(a.binarystringcolumn)) = udf_BIN_TO_ASCII(a.binarystringcolumn)

Jonathan
Gaming will never be the same
Go to Top of Page

vladimir_grigoro
Yak Posting Veteran

62 Posts

Posted - 2004-01-15 : 02:22:48
Thanks to all of you!!!

I think that we found the solution of the probmel, which is a little bit complicated but works fine for me - I think.

You are great guys. Thank you!!!

The Rebel
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2004-01-15 : 09:26:25
quote:
Originally posted by vladimir_grigoro

Thanks to all of you!!!

I think that we found the solution of the probmel, which is a little bit complicated but works fine for me - I think.

You are great guys. Thank you!!!

The Rebel



Why not show us what you came up with?



Brett

8-)
Go to Top of Page
   

- Advertisement -