2011-02-09 16 views
8

L'esportazione data/ora è "CAST (0x0000987C00000000 AS DateTime)", ma quando voglio riportarlo in datetime. È un valore NULL. come posso tornare a datetime di nuovo.come trasmettere l'esadecimale a varchar (datetime)?

+0

Che tipo di valore datetime ti aspetti da questo? Non sono sicuro di aver capito. –

+0

Oh ragazzo ... Come sei arrivato a questo valore esadecimale? – Mchl

+0

Restituisce '2006-11-17 00: 00: 00.000' per me in SQL Server. Stai cercando di utilizzare il formato binario di SQL Server in MySQL? Non sono sicuro del motivo per cui vorresti farlo, ma in ogni caso è memorizzato come 2 numeri interi con i primi 4 byte che sono i giorni dal 1 ° gennaio 1900 e il 2 ° è il numero di tick dalla mezzanotte (ogni tick è 0.33ms) –

risposta

11

Sembra il formato SQL Server datetime. Internamente questo è memorizzato come 2 interi con i primi 4 byte che sono i giorni dal 1 ° gennaio 1900 e il 2 ° è il numero di zecche dalla mezzanotte (ogni tick è 1/300 di secondo).

Se avete bisogno di utilizzare questo in MySQL si potrebbe fare

SELECT 
     CAST(
      '1900-01-01 00:00:00' + 
      INTERVAL CAST(CONV(substr(HEX(BinaryData),1,8), 16, 10) AS SIGNED) DAY + 
      INTERVAL CAST(CONV(substr(HEX(BinaryData),9,8), 16, 10) AS SIGNED)* 10000/3 MICROSECOND 
     AS DATETIME) AS converted_datetime 
FROM 
(
SELECT 0x0000987C00000000 AS BinaryData 
UNION ALL 
SELECT 0x00009E85013711EE AS BinaryData 
) d 

Returns

converted_datetime 
-------------------------- 
2006-11-17 00:00:00 
2011-02-09 18:52:34.286667 

(Grazie a Ted Hopp per the solution nel dividere i dati binari)

+0

Esportazione sqlserver in questo formato ("CAST (0x0000987C00000000 AS DateTime)") e ho più dati di migrazione dati di data e ora in mysql quindi, come posso fare. – Zrot

+0

@Martin: 'SELECT HEX (0x0000987C00000000 & 0xFFFFFFFF), HEX (0x0000987C00000000 >> 32);' – Mchl

+0

@Mhcl - Grazie! Qualche idea sul perché 'CAST (substr (BinaryData, 1,4) AS SIGNED)' non funziona? Se faccio solo 'SELECT substr (BinaryData, 1,4)' e lo guardo nel visualizzatore BLOB nel workbench SQL sembra identico a quello mostrato se io faccio 'SELECT 0x0000987C' –

8

Non proprio l'aggiunta di tutto ciò che non è stato dichiarato ma l'ho usato per creare una funzione MySql dal codice precedente. Posso quindi utilizzare un Trova e sostituisci RegEx (in Notepad ++) per sostituire il CAST (0xblahblahblah AS DATETIME) con sp_ConvertSQLServerDate (0xblahblahblah).

create function sp_ConvertSQLServerDate(dttm binary(16)) 
returns datetime 
return CAST(
     '1900-01-01 00:00:00' + 
     INTERVAL CAST(CONV(substr(HEX(dttm),1,8), 16, 10) AS SIGNED) DAY + 
     INTERVAL CAST(CONV(substr(HEX(dttm),9,8), 16, 10) AS SIGNED)* 10000/3 MICROSECOND 
AS DATETIME); 
+0

Questo è eccellente, grazie. – toxaq

+0

Esattamente quello che mi serviva per aiutare a convertire qualcosa da SiteFinity in WordPress. Grazie! – LOLapalooza

1

Ecco un programma Java che ho fatto.

Il programma analizza il file data (cambio de nome sul codice sotto) per

CAST(0x... AS DateTime) 

e li sostituisce con i loro rispettivi

CAST('yyyy-MM-dd HH:mm:ss.SSS' AS DateTime) 

.

Per esempio, se si considera che i rendimenti SELECT CAST (0x00009CEF00A25634 as datetime)2009-12-30 09:51:03.000, il programma analizza il file per CAST(0x00009CEF00A25634 AS DateTime) e li sostituisce con CAST('2009-12-30 09:51:03.000' AS DateTime).

L'ho usato per convertire uno script generato da SQL Server in qualcosa che un database incorporato H2 poteva capire.

Anche se ha funzionato bene per me, ti consiglio di controllarlo (basta eseguire alcuni dati di test e vedere) prima di utilizzare i dati reali.

import java.io.*; 
import java.text.*; 
import java.util.*; 
import java.util.regex.*; 

public class ReplaceHexDate { 

    public static void main(String[] args) throws Exception { 
     String inputFile = "C:/input.sql"; 
     String inputEncoding = "UTF-8"; 
     String outputFile = "C:/input-replaced.sql"; 
     String outputEncoding = "UTF-8"; 

     BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), inputEncoding)); 
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), outputEncoding)); 

     String line; 
     while ((line = br.readLine()) != null) { 
      if (line.indexOf("CAST(0x") > -1) { 
       bw.write(replaceHexWithDate(line)); 
      } else { 
       bw.write(line); 
      } 
      bw.newLine(); 
     } 
     br.close(); 
     bw.flush(); 
     bw.close(); 
    } 

    private static String replaceHexWithDate(String sqlLine) throws ParseException { 
     Pattern castPattern = Pattern.compile("(CAST\\()(0x[A-Fa-f0-9]{16})(AS DateTime\\))"); 
     Matcher m = castPattern.matcher(sqlLine); 
     while (m.find()) { 
      String s = m.group(2); 
      sqlLine = sqlLine.replace(s, "'"+sqlServerHexToSqlDate(s)+"'"); 
     } 
     return sqlLine; 
    } 

    public static String sqlServerHexToSqlDate(String hexString) throws ParseException { 
     String hexNumber = hexString.substring(2); // removes the leading 0x 
     String dateHex = hexNumber.substring(0, 8); 
     String timeHex = hexNumber.substring(8, 16); 

     long daysToAdd = Long.parseLong(dateHex, 16); 
     long millisToAdd = (long) (Long.parseLong(timeHex, 16) *10/3); 

     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 

     Calendar startingCal = Calendar.getInstance(); 
     String startingDate = "1900-01-01 00:00:00.000"; 
     startingCal.setTime(sdf.parse(startingDate)); 

     Calendar convertedCal = Calendar.getInstance(); 
     convertedCal.setTime(sdf.parse(startingDate)); 
     convertedCal.add(Calendar.DATE, (int) daysToAdd); 
     convertedCal.setTimeInMillis(convertedCal.getTimeInMillis() + millisToAdd); 

     return sdf.format(convertedCal.getTime()); 
    } 
} 
2

Questa è la stessa istruzione select per PostgreSQL:

(32) valori
SELECT '1900-01-01 00:00:00'::date + 
    (('x'||substring(x::text,3,8))::bit(32)::int::text||'days')::interval + 
    ((('x'||substring(x::text,11,8))::bit(32)::int /300)::text||' seconds')::interval 
FROM (VALUES 
    ('0x00009fff00e24076'), 
    ('0x00009ff10072d366'), 
    ('0x00009ff10072ce3a'), 
    ('0x00009ff10072c5e2'), 
    ('0x00009ff10072bc3c')) as x(x); 

bit PostgreSQL devono iniziare con 'x' valore invece di 0.

+0

Questa domanda è contrassegnata come MySql. Per favore considera di aggiungere questa risposta a http://stackoverflow.com/q/7580700/73226 –

1

Utilizzando Notepad ++ regex sostituire

cast[(]0x([0-9A-F]{16}) As DateTime[)] 

CAST('1900-01-01 00:00:00' + INTERVAL CAST(CONV(substr(HEX(0x\1),1,8), 16, 10) AS SIGNED) DAY + INTERVAL CAST(CONV(substr(HEX(0x\1),9,8), 16, 10) AS SIGNED)* 10000/3 MICROSECOND AS DATETIME) 

Questo sostituirà

CAST(0x0000A26900F939A8 AS DateTime) 

a

CAST('1900-01-01 00:00:00' + INTERVAL CAST(CONV(substr(HEX(0x0000A26900F939A8),1,8), 16, 10) AS SIGNED) DAY + INTERVAL CAST(CONV(substr(HEX(0x0000A26900F939A8),9,8), 16, 10) AS SIGNED)* 10000/3 MICROSECOND AS DATETIME), 
0

MSSQL codice esadecimale per data e dateTime sono diversi.

Per data in fomate come 0x00000000 è possibile utilizzare questa funzione Postgres:

CREATE FUNCTION convertedata(text) RETURNS timestamp without time zone 
as $$ SELECT '0001-01-01 00:00:00'::date + (('x'|| 
(regexp_replace(
substring($1::text,3,8)::text, 
'(\w\w)(\w\w)(\w\w)(\w\w)', 
'\4\3\2\1'))::text 
)::bit(32)::int::text||'days')::interval $$ 
LANGUAGE SQL; 

quindi provare

select convertedata('0x0E360B00') 
0

Per chi cerca una soluzione in C#. Ad esempio quando si leggono dati di database con script.

 string pattern = @"CAST\(0x(\w{8})(\w{8}) AS DateTime\)"; 
     Regex r = new Regex(pattern); 
     Match m = r.Match(hex);    

     int d = System.Convert.ToInt32("0x" + m.Groups[1].Value, 16); 
     int t = System.Convert.ToInt32("0x" + m.Groups[2].Value, 16); 

     DateTime converted = new DateTime(1900, 1, 1).AddDays(d).AddSeconds(t/300); 

Qui ho usato espressioni regolari dato che il mio ingresso è il seguente modulo "CAST (0x0000A53E00E1A17B AS DateTime)", ma è possibile utilizzare substring() o qualsiasi altra cosa per ottenere la stringa DateTime.

Problemi correlati