AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 323235
Accepted
smoka smokov
smoka smokov
Asked: 2023-02-09 07:25:43 +0800 CST2023-02-09 07:25:43 +0800 CST 2023-02-09 07:25:43 +0800 CST

Pesquisa de padrão varbinary

  • 772

Estou tentando fazer uma consulta que passa por dados varbinary. O problema é que não consigo terminar o que estou tentando alcançar. O que você deve saber sobre a coluna é varbinary(50) e os padrões que ocorrem não têm ordem específica de escrita, o que significa que cada prefixo pode estar em qualquer lugar, desde que tenha 3 bytes (0x000000) O primeiro byte é o prefixo, o segundo e o terceiro são dados de valor que eu estou olhando para verificar se está dentro do intervalo que eu gosto. Todos os dados são escritos assim.

O que eu tentei:

DECLARE @t TABLE (
    val VARBINARY(MAX)
)

INSERT INTO @t SELECT 0x00000100000000000000000000000000000000000000000000000000
INSERT INTO @t SELECT 0x00001000000000000000000000000000000000000000000000000000
INSERT INTO @t SELECT 0x00010000000000000000000000000000000000000000000000000000
INSERT INTO @t SELECT 0x00100000000000000000000000000000000000000000000000000000
INSERT INTO @t SELECT 0x00000f00000000000000000000000000000000000000000000000000

declare @pattern varbinary(max)
declare @pattern2 varbinary(max)
set @pattern = 0x0001
set @pattern2 = @pattern+0xFF

select @pattern,@pattern2

SELECT
    *
FROM @t
WHERE val<@pattern
OR val>@pattern2

Isso foi um fracasso total, os padrões eram precisos até 2 símbolos, se eu usasse 4 símbolos como padrão, funcionaria apenas se o padrão estivesse na posição predefinida. Eu tentei a combinação disso e tudo abaixo.

WHERE CONVERT(varbinary(2), val) = 0xdata

também isso:

select * 
from table
where CONVERT(varchar(max),val,2) like '%data%'

O que funciona muito bem para pesquisar padrões exatos, mas não para intervalos, preciso de uma combinação de ambos.

Eu preciso de algo que detecte isso por conta própria enquanto eu apenas especifico um ponto inicial e final para procurar entre como a maior variação de número seria '26ffff', mas limitá-lo a algo como 'ff00' é aceitável para o que estou procurando por.

Meu melhor palpite é de 2 números definidos, sendo 1 o intervalo máximo permitido e o 2º para um limite, para que não passe por todos os resultados possíveis. Mas eu ficaria feliz em tudo o que funciona.

A origem dos dados está relacionada a um servidor de jogo que armazena os dados dessa forma. Existem os prefixos predefinidos que são o tipo de estatística e o restante dos dados é o valor numérico real da estatística. Os dados são representados por intervalos de dados de 6 caracteres. Aqui está uma amostra do fluxo de dados. É sempre 6-6-6-6-6, desde que haja espaço para gravar os dados, pois é limitado a 50 caracteres. 0x0329000414000B14000C14000D0F00177800224600467800473C00550F00000000000000000000000000

Os grupos estão sempre na moda de 3 bytes, minha ideia é usar o primeiro byte para restringir a pesquisa e usar os segundos 2 bytes para filtrá-lo. Só não sei como fazer isso de maneira eficaz. Se o padrão de 3 bytes for violado, os dados se tornarão ilegíveis, o que significa que, mesmo que você não precise do byte extra, ainda precisará contá-lo, caso contrário, os dados serão quebrados, exemplo de dados em funcionamento.

0x032900'041400'

exemplo de dados corrompidos:

 0x0329'041400'

O único problema que eu poderia pensar é quando o prefixo e parte do valor são verdadeiros exemplo:

0x262600

A menos que a consulta seja especificamente solicitada para ler os dados na sequência de 3 bytes, o que significa que o primeiro byte é sempre um prefixo e os outros 2 bytes são valores.

P: Isso pode ser usado como um indicador de alinhamento para que o primeiro byte diferente de zero após pelo menos 3 bytes zero indique o início de um grupo?

R: Sim, mas isso é improvável, eu quis dizer isso, embora possível, seria escrito em ordem como:

0x260000'270000'

Não pularia para frente um grupo inteiro de 3 bytes preenchido sem dados. Esse tipo de entrada ocorreria se alguém inserisse manualmente no banco de dados, o servidor não faz registros com lacunas como essas que eu saiba:

0x260000'000000'270000'

O mais próximo do meu resultado desejado como uma consulta de trabalho é isso, mas isso é terrível, funcionaria para pequenos intervalos, mas qualquer coisa maior seria tedioso.

select * from @t 
where (CONVERT(varchar(max),val,2) like '%262100%' or 
CONVERT(varchar(max),attr,2) like '%262200%' or 
etc...)

Metas:

  1. Localizando o prefixo (primeiro par de dados binários)
  2. Definindo um valor máximo após o prefixo, tudo acima desse limite será listado nos resultados. Digamos que '26' seja o prefixo, o maior número permitido depois é '9600' ou '269600'. Basicamente, qualquer dado que exceda esse padrão '269600' deve ser detectado, exemplo '269700'. ou o resultado da consulta postaria isso:

selecione * da tabela onde CONVERT(varchar(max),attr,2) como '%269700%'


Estou tentando obter uma consulta que pode percorrer os dados varbinary de uma tabela que procura um resultado específico dentro do exemplo de parâmetros definidos:

0x263700, os dados são divididos em segmentos de 3 bytes, 1 byte é o cabeçalho que será usado para um padrão de pesquisa, os outros 2 bytes são o valor que tenho que verificar se está dentro do intervalo definido por exemplo: tudo acima de '3700' (+ 1 bit de diferença) o valor binário até 'FFFF' seria classificado como resultado ou o resultado plausível máximo seria '26FFFF'. Isso não é para um fluxo de dados específico ser alternado um por um.

sql-server
  • 1 1 respostas
  • 93 Views

1 respostas

  • Voted
  1. Best Answer
    Martin Smith
    2023-02-10T02:38:18+08:002023-02-10T02:38:18+08:00

    Provavelmente é mais fácil apenas dividir o valor em blocos de três bytes e examinar cada bloco individualmente.

    Como o comprimento máximo é de apenas 50 e você não parece querer olhar para uma janela deslizante de três bytes, é viável apenas codificar os valores de limite na consulta (caso contrário, você pode criar uma tabela com números sequenciais ou usar para evitar GENERATE_SERIESisso )

    O seguinte usa uma junção para retornar o valor de tripleto correspondente e id- você pode preferir mudar para a WHERE EXISTSse quiser apenas a linha correspondente e não quiser várias linhas no caso de várias partes do mesmo valor binário corresponderem.

    DECLARE @YourTable table
    (
    Id INT PRIMARY KEY,
    Val VARBINARY(50)
    )
    
    INSERT @YourTable
    VALUES (1, 0x0329000414000B14000C14000D0F00177800224600467800473C00550F00000000000000000000000000),
           (2, 0x0329002637000B14000C14000D0F00177800224600467800473C00550F00000000000000000000000000);
    
    
    SELECT Id, Triplet
    FROM @YourTable T
    JOIN (VALUES (1),(4),(7),(10),(13),(16),(19),(22),(25),(28),(31),(34),(37),(40),(43),(46),(49)) Nums(Num) ON Num <= DATALENGTH(T.Val)
    CROSS APPLY (VALUES (SUBSTRING(T.Val, Num, 3))) V(Triplet)
    WHERE Triplet BETWEEN 0x263700 AND 0x2637FF
    

    Você também deve revisar se o acima funciona como deseja para o caso em que o comprimento binário não é divisível por três e o último segmento é menor que três bytes (talvez você também precise de um predicado?) DATALENGTH(Triplet) = 3.

    • 5

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve