none
Hexa bzw. Binärezahlen von einem Datensatz auf einen anderen übernehmen RRS feed

  • Frage

  • Hallo :)

    ich habe beispielsweise zwei Datensätze über zwei Autos.

    Nun möchte ich die Eigenschaften von einem Auto auf das andere Auto übernehmen.

    Diese Eigenschaften sind durch Hex bzw, Binäre Zahlen defeniert

    Bei einer Eigenschaft ist es nicht so problematisch...

    Aber bei mehreren??

    Was ich bisher gemacht habe:
    1. Auslesen der gesetzten Zahlen von beiden Datensätzen.
    2. Prüfe ob diese ungleich sind:

    select @FLAGS_Auto_1 = Auto.FLAGS from Auto
                where Auto = @Auto_1
    select @FLAGS_Auto_2 = Auto.FLAGS from Auto
                where Auto = @Auto_2
    if @FLAGS_Auto_1 <> @FLAGS_Auto_2
    begin
      update Auto set FLAGS = FLAGS + @FLAGS_Auto_1
      WHERE Auto = @Auto_2
    end 
    


    Diese Zeile stört mich:

    if @FLAGS_Auto_1 <> @FLAGS_Auto_2
    

    Denn es kann sein, dass manche Zahlen, die in der Variable

    @FLAGS_Auto_2
    

    vorhanden sind bzw. gesetzt sind und manche nicht....

    Ich habe insgesamt 15 Eigenschaft ==> 15Hex -Zahlen. Soll ich eine Schleife bauen um jeden einzelnen alten Wert mit dem neuen-Wert zu prüfen?

    ode kann man das irgendwie geschickter gestalten?

    danke für jeden Tipp

     

     

    Dienstag, 2. August 2011 10:55

Antworten

  • Das hat Stefan doch alles sehr schön beschrieben, oder?
    Bastelt man die zwei Antworten zusammen, erhält man:
    UPDATE A2
    SET A2.FLAGS = A2.FLAGS | A1.FLAGS
    FROM [Auto] A2 ,
     [Auto] A1
    WHERE A2.[Auto] = @Auto_2
     AND A1.[Auto] = @Auto_1
     AND A2.Flags <> A1.Flags 
    ;
    Mit dem bitweisen |-Operator wird zwischen zwei Ausdrücken ein bitweises logisches OR ausgeführt, indem die jeweils entsprechenden Bits der beiden Ausdrücke verarbeitet werden. Ein Ergebnisbit wird dann auf den Wert 1 festgelegt, wenn mindestens eines der Bits (für das aktuell aufzulösende Bit) der Eingabeausdrücke den Wert 1 aufweist. Falls keines der Bits in den Eingabeausdrücken den Wert 1 hat, wird das entsprechende Bit im Ergebnis auf 0 festgelegt.
     
     
     
    Einen schönen Tag noch,
    Christoph

    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu
    • Als Antwort markiert BLRBeginner Mittwoch, 3. August 2011 10:11
    Mittwoch, 3. August 2011 06:32

Alle Antworten

  • Deine Szenario ist unabhängig davon das du hexadezimale Werte speicherst.

    Wenn ich vor lauter Autos richtig liege, sollte es auch so gehen:

    UPDATE A2
    SET  A2.FLAGS = A2.FLAGS + A1.FLAGS
    FROM [Auto] A2 ,
      [Auto] A1
    WHERE A2.[Auto] = @Auto_2
      AND A1.[Auto] = @Auto_1
      AND A2.Flags <> A1.Flags ;

    Wobei ich die Logik hinter dem Gleichheitstest nicht verstehe das Addieren hilft hier nämlich nicht. Da

    DECLARE @F1 INT = 8 + 4 + 2 + 1 ;
    DECLARE @F2 INT = 4 + 2 + 1 ;
    
    IF ( @F1 <> @F2 )
     SELECT @F1 + @F2, @F1 | @F2 ;

    22 ist halt falsch, da nicht 15. Du brauchst das bitweise ODER.

    btw, das Speichern von binär kodierten Werten verletzt die erste Normalform.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann

    Dienstag, 2. August 2011 11:16
    Moderator
  • ja, eignetlich hab ich es so gemacht

     

    if @flags & 0x01000000 = 0x01000000
    
    begin
    
    print 'zahl ist in dieser zahl drin'
    
    end
    

    durch die "Verundung" werden die Zahlen bitweise miteinander vergliechen.

    Aber das ist nur eine Zahl. Ich habe beispielsweise: 0x01842100.

    Diese Zahl besteht aus 5 anderen Hexazahlen, die alle verundet werden müssten um zu schauen, ob diese zahlen schon in nem anderen Datensatz enthalten sind oder nicht. Aber ich möchte nicht fünf if-Anweisungen machen....wie kann man alle gesetzten zahlen auf einmal verunden?

    Dienstag, 2. August 2011 16:40
  • Nochmal, das hat nichts mit der Darstellung der Zahl zu tun. Und du brauchst kein UND sondern ein ODER.

    DECLARE @F1 INT = 8 + 4 + 2 + 1 ;
    DECLARE @F2 INT = 4 + 2 + 1 ;
    
    IF ( @F1 <> @F2 )
     SELECT @F1 + @F2, @F1 | @F2, @F1 & @F2 ;
    

    Denke mal intensiv über | nach.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Dienstag, 2. August 2011 21:55
    Moderator
  • hhmm...das heisst, wenn ich nur die zahl 8 in die Variable @F2 übernehmen will

    dann schreibe ich:

     

    if(@F1 <> @F2)
    
    select @F1|@F2
    
    Dann übernimmt @F1 eben diese Differenz oder?

     

    Mittwoch, 3. August 2011 05:41
  • Nein, dem ist nicht so, wenn auch das Ergebnis so aussieht. Es geht hier um grundlegende Bitoperationen:

    http://sqlfool.com/2009/02/bitwise-operations/
    http://www.vonhaeftens-blog.de/files/BIT_SQL/bit.html
    http://www.oreilly.de/catalog/cplus2ger/chapter/ch11.pdf


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Mittwoch, 3. August 2011 06:23
    Moderator
  • Das hat Stefan doch alles sehr schön beschrieben, oder?
    Bastelt man die zwei Antworten zusammen, erhält man:
    UPDATE A2
    SET A2.FLAGS = A2.FLAGS | A1.FLAGS
    FROM [Auto] A2 ,
     [Auto] A1
    WHERE A2.[Auto] = @Auto_2
     AND A1.[Auto] = @Auto_1
     AND A2.Flags <> A1.Flags 
    ;
    Mit dem bitweisen |-Operator wird zwischen zwei Ausdrücken ein bitweises logisches OR ausgeführt, indem die jeweils entsprechenden Bits der beiden Ausdrücke verarbeitet werden. Ein Ergebnisbit wird dann auf den Wert 1 festgelegt, wenn mindestens eines der Bits (für das aktuell aufzulösende Bit) der Eingabeausdrücke den Wert 1 aufweist. Falls keines der Bits in den Eingabeausdrücken den Wert 1 hat, wird das entsprechende Bit im Ergebnis auf 0 festgelegt.
     
     
     
    Einen schönen Tag noch,
    Christoph

    Microsoft SQL Server MVP
    www.insidesql.org/blogs/cmu
    • Als Antwort markiert BLRBeginner Mittwoch, 3. August 2011 10:11
    Mittwoch, 3. August 2011 06:32
  • oohh danke sehr für die links, ist sehr interessant, und einen abschnitt hab ich rausgenommen, den ich mir auch so gedacht habe:

    http://www.vonhaeftens-blog.de/files/BIT_SQL/bit.html#x1-20001

     

    Bit Nr.2: Nimm die Zahl 4:
    
    							
    0	0	0	0	0	1	0	0
    							
    
    Dies ist nichts anderes als die Zahl 22 = 4. Dann verknüpft man diese und die zu untersuchende Zahl durch ein logisches "UND":
    
    							
    0	0	1	0	1	1	1	1
    							
    
    UND
    
    							
    0	0	0	0	0	1	0	0
    							
    
    Und dabei kommt heraus:
    
    							
    0	0	0	0	0	1	0	0
    							
    Also wieder 4. Man sieht sofort: Wenn bei diesem logischen UND dieselbe Zahl herauskommt, die man "dazugeundet" hat, so ist das entsprechende Bit gesetzt. 


    Und genau das wollte ich auch umsetzen. Ich hatte die zahl 18421000

    Diese Zahl besteht dann aus 10000000

                                               8000000

                                                 400000

                                                   20000

                                                     1000

                                           --------------

                                            18421000

    Und um zu prüfen, ob wirklich all diese vier Zahlen gesetzt sind (also bitweise) wollte ich VERUNDEN, aber dann müsste ich vier If-Anweisungen mit logischem UND bauen. Und das war mir zu umständlich, deswegen wollte ich eine geschicketere Variante erfahren

    Da nun ja manche zahlen gesetzt sind und manche nicht, muss ich dann verodern :)

    Mittwoch, 3. August 2011 08:26