복붙노트

[SQL] 어떻게 VARCHAR (날짜)에 16 진수 변환하려면?

SQL

어떻게 VARCHAR (날짜)에 16 진수 변환하려면?

나는 내보내는 날짜는 "CAST (0x0000987C00000000 AS 날짜 시간)"입니다 있지만 내가 다시 datetime.It에 그것을 얻을 할 때 NULL 값입니다. 내가 어떻게 다시 날짜에 그것을 얻을 수 있습니다.

해결법

  1. ==============================

    1.는 SQL Server와 같은 그 모습 날짜 형식입니다. 내부적으로는 제 4 바이트 1번째 일월 1900 년 이후 일 부이고 2는 자정 이후 틱 수 (각 눈금은 1/300 초이다) 인 2 개 정수로서 저장된다.

    는 SQL Server와 같은 그 모습 날짜 형식입니다. 내부적으로는 제 4 바이트 1번째 일월 1900 년 이후 일 부이고 2는 자정 이후 틱 수 (각 눈금은 1/300 초이다) 인 2 개 정수로서 저장된다.

    당신의 MySQL이를 사용해야하는 경우 당신은 할 수

    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
    

    보고

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

    (이진 데이터 분할의 솔루션 테드 Hopp에게 감사)

  2. ==============================

    2.정말 언급되지 않은 것을 추가하지만 위의 코드에서 MySQL의 기능을 만들려면이를 사용하지 않습니다. 나는 다음 정규식 찾기를 사용하고 sp_ConvertSQLServerDate (0xblahblahblah)와 CAST (0xblahblahblah AS DATETIME)를 대체하기 위해 (++ 메모장에서) 대체 할 수있다.

    정말 언급되지 않은 것을 추가하지만 위의 코드에서 MySQL의 기능을 만들려면이를 사용하지 않습니다. 나는 다음 정규식 찾기를 사용하고 sp_ConvertSQLServerDate (0xblahblahblah)와 CAST (0xblahblahblah AS DATETIME)를 대체하기 위해 (++ 메모장에서) 대체 할 수있다.

    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);
    
  3. ==============================

    3.이것은 PostgreSQL의에 대해 동일한 select 문입니다 :

    이것은 PostgreSQL의에 대해 동일한 select 문입니다 :

    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);
    

    PostgreSQL는 (32)의 값이 'X'의 값 대신에 0으로 시작할 필요 비트.

  4. ==============================

    4.여기에 내가했던 자바 프로그램입니다.

    여기에 내가했던 자바 프로그램입니다.

    다음은 프로그램 (아래 코드에서 이름을 드 변경)에 대해, 지정된 파일을 검색

    CAST(0x... AS DateTime)
    

    그리고 각각의로 대체

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

    .

    51 : : 예를 들어, SELECT의 CAST (날짜로 0x00009CEF00A25634가) 2009-12-30 09 반환 고려 03.000이 프로그램은 CAST와 CAST (0x00009CEF00A25634 AS 날짜 시간) 및 대체합니다 그들을 위해 파일을 검색 ( '2009-12-30 09 : 51 : 03.000 'AS 날짜 시간).

    나는 H2 포함 된 데이터베이스가 이해할 수있는 일에 SQL 서버 생성 된 스크립트를 변환하는 데 사용했다.

    나를 위해 벌금을 근무하지만, 난 당신이 실제 데이터를 사용하기 전에 (그냥 몇 가지 테스트 데이터에서 실행 참조)을 확인 좋습니다.

    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());
        }
    }
    
  5. ==============================

    5.메모장 ++를 사용하여 대체 정규식

    메모장 ++를 사용하여 대체 정규식

    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)
    

    이것은 대체합니다

    CAST(0x0000A26900F939A8 AS DateTime)
    

    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), 
    
  6. ==============================

    6.날짜와 DateTime의 MSSQL의 16 진수 코드가 다릅니다.

    날짜와 DateTime의 MSSQL의 16 진수 코드가 다릅니다.

    0x00000000의 같은 형식으로 날짜를 들어이 포스트 그레스 기능을 사용할 수 있습니다 :

    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;
    

    다음 시도

    select convertedata('0x0E360B00')
    
  7. ==============================

    7.사람들을 위해 C #에서 솔루션을 찾고. 예를 들어 스크립트 데이터베이스 데이터를 읽을 때.

    사람들을 위해 C #에서 솔루션을 찾고. 예를 들어 스크립트 데이터베이스 데이터를 읽을 때.

            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);
    

    여기 내 입력 양식은 다음 "CAST (0x0000A53E00E1A17B AS 날짜 시간)"에 있기 때문에 나는 정규식을 사용하지만, 당신은 날짜 시간 문자열을 얻을 SUBSTRING () 또는 무엇이든 사용할 수 있습니다.

  8. from https://stackoverflow.com/questions/4946292/how-to-cast-the-hexadecimal-to-varchardatetime by cc-by-sa and MIT license