Вы можете преобразовать шестнадцатеричную строку в двоичные данные и сохранить ее в столбце VARCHAR или VARBINARY. Я предпочитаю VARCHAR из-за довольно ограниченных CAST, доступных для VARBINARY.
Чтобы преобразовать шестнадцатеричную строку в двоичную и сохранить ее в VARCHAR, используйте функцию hextoraw, предоставляемую с помощью набора расширений SQL. Это включено в Netezza, но должно быть настроено и доступно вашим администратором.
Чтобы преобразовать шестнадцатеричную строку в двоичную и сохранить ее в VARBINARY, используйте функцию hex_to_binary, включенную в Netezza (добавлено в v 7.2).
drop table test_table if exists;
DROP TABLE
create table test_table (col1 varchar(50), col2 varbinary(50));
CREATE TABLE
insert into test_table values (hextoraw('464F4F'), hex_to_binary('464F4F'));
INSERT 0 1
select * from test_table;
COL1 | COL2
------+-----------
FOO | X'464F4F'
(1 row)
Оттуда вам понадобится UDF для обработки вычислений бит, которые вы хотите сделать. Я собрал три простых UDF, которые, я считаю, подойдут вашей цели.
FirstBit возвращает позицию первого ненулевого бита. BitCount возвращает общее количество ненулевых битов. CharToBase2 преобразует двоичные значения в VARCHAR из 1s и 0s.
Я думаю, что первые два получат конечный результат, который вам нужен без третьего, но в случае, если вы все еще хотели этого, он здесь.
select firstbit(hextoraw('0000')), bitcount(hextoraw('0000')), chartobase2(hextoraw('0000'));
FIRSTBIT | BITCOUNT | CHARTOBASE2
----------+----------+------------------
-1 | 0 | 0000000000000000
(1 row)
select firstbit(hextoraw('0001')), bitcount(hextoraw('0001')), chartobase2(hextoraw('0001'));
FIRSTBIT | BITCOUNT | CHARTOBASE2
----------+----------+------------------
15 | 1 | 0000000000000001
(1 row)
select firstbit(hextoraw('FFFF')), bitcount(hextoraw('FFFF')), chartobase2(hextoraw('FFFF'));
FIRSTBIT | BITCOUNT | CHARTOBASE2
----------+----------+------------------
0 | 16 | 1111111111111111
(1 row)
Вот источники для каждого. Обратите внимание, что я ужасный C++-кодер и, скорее всего, буду уволен, если бы это была моя работа, поэтому предостерегайте emptor.
BitCount.cpp
#include "udxinc.h"
#include <string.h>
using namespace nz::udx;
class BitCount : public Udf
{
public:
static Udf* instantiate();
ReturnValue evaluate()
{
StringArg* str = stringArg(0);
int32 retval = 0;
for(int i=0; i< str->length; i++)
{
for (int y=7; y>=0 ; y--)
{
if ((str->data[i] & (unsigned char)pow(2,y)) > 0)
{
retval++;
}
}
}
NZ_UDX_RETURN_INT32(retval);
}
};
Udf* BitCount::instantiate()
{
return new BitCount;
}
FirstBit.cpp
#include "udxinc.h"
#include <string.h>
using namespace nz::udx;
class FirstBit : public Udf
{
public:
static Udf* instantiate();
ReturnValue evaluate()
{
StringArg* str = stringArg(0);
int32 retval = -1;
for(int i=0; i< str->length; i++) {
for (int y=7; y>=0 ; y--) {
if ((str->data[i] & (unsigned char)pow(2,y)) > 0)
{
retval = i*8 + 7 - y;
}
if (retval > -1) break;
}
if (retval > -1) break;
}
NZ_UDX_RETURN_INT32(retval);
}
};
Udf* FirstBit::instantiate()
{
return new FirstBit;
}
CharToBase2.каст
#include "udxinc.h"
#include <string.h>
using namespace nz::udx;
class CharToBase2 : public Udf
{
public:
static Udf* instantiate();
ReturnValue evaluate()
{
StringArg* str = stringArg(0);
StringReturn* result = stringReturnInfo();
result->size = str->length*8;
//unsigned char stringbyte = 0 ;
for(int i=0; i< str->length; i++)
{
for (int y=7; y>=0 ; y--)
{
if ((str->data[i] & (unsigned char)pow(2,y)) == 0) {
result->data[i*8 + 7 - y] = '0'; }
else {
result->data[i*8 + 7 - y] = '1'; }
}
}
NZ_UDX_RETURN_STRING(result);
}
uint64 calculateSize() const
{
return sizerStringSizeValue(sizerStringArgSize(0)*8);
}
};
Udf* CharToBase2::instantiate()
{
return new CharToBase2;
}
Наконец, вот сценарии, которые я использовал для компиляции и установки каждого из них.
install_firstbit.sh DBNAME
DB=$1
if [[ -z $DB ]]; then
DB=$NZ_DATABASE
fi
if [[ -z $DB ]]; then
print "Usage: install <database>"
return 1
fi
export NZ_DATABASE="${DB}"
nzudxcompile FirstBit.cpp \
--fenced \
--sig "FirstBit(varchar(any))" \
--return "integer" \
--class "FirstBit"
rm FirstBit.o_*
install_bitcount.sh DBNAME
DB=$1
if [[ -z $DB ]]; then
DB=$NZ_DATABASE
fi
if [[ -z $DB ]]; then
print "Usage: install <database>"
return 1
fi
export NZ_DATABASE="${DB}"
nzudxcompile BitCount.cpp \
--fenced \
--sig "BitCount(varchar(any))" \
--return "integer" \
--class "BitCount"
rm BitCount.o_*
install_chartobase2.sh DBNAME
DB=$1
if [[ -z $DB ]]; then
DB=$NZ_DATABASE
fi
if [[ -z $DB ]]; then
print "Usage: install <database>"
return 1
fi
export NZ_DATABASE="${DB}"
nzudxcompile CharToBase2.cpp \
--fenced \
--sig "CharToBase2(varchar(any))" \
--return "varchar(any)" \
--class "CharToBase2"
rm CharToBase2.o_*
Кажется, что вы хотите преобразовать varchar, который содержит шестнадцатеричное представление в A) двоичное представление этого шестнадцатеричного значения или B) представление varchar двоичного представления с использованием символов ASCII '0' и '1 ». Можете ли вы уточнить, хотите ли вы A или B? – ScottMcG
B - это то, что я ищу. \t Просто чтобы развернуть это - в конечном итоге, мне нужно сделать следующее: 1- найти позицию первого 1 в двоичной строке (0 в случае «0xFFFFFFFFFFFFFFFF»). 2- найти счетчик 1 в двоичной строке (64 в случае «0xFFFFFFFFFFFFFFFF») - с этой точки зрения B, вероятно, достаточно – user3206440
Похоже, потребуется явное преобразование, но [это не поддерживается Netezza] (http : //www-01.ibm.com/support/knowledgecenter/SSULQD_7.1.0/com.ibm.nz.dbu.doc/r_dbuser_supported_im_ex_casts.html). Так выглядит (мне), как конвертация, возможно, придется делать вручную ... –