{"id":1355,"date":"2014-11-29T19:53:50","date_gmt":"2014-11-29T11:53:50","guid":{"rendered":"http:\/\/blog.qdac.cc\/?p=1355"},"modified":"2014-11-29T21:41:22","modified_gmt":"2014-11-29T13:41:22","slug":"%e5%88%a9%e7%94%a8qjson%e8%bd%ac%e6%8d%a2firedac%e6%95%b0%e6%8d%aejson%e6%a0%bc%e5%bc%8f","status":"publish","type":"post","link":"https:\/\/blog.qdac.cc\/?p=1355","title":{"rendered":"\u5229\u7528QJson\u8f6c\u6362FireDAC\u6570\u636eJSON\u683c\u5f0f"},"content":{"rendered":"<p>\u9996\u5148\u6211\u4eec\u6765\u770bFireDAC\u7684\u6570\u636e\u5bf9\u8c61\uff0c\u770b\u770b\u5b83\u7684\u5185\u90e8\u4fdd\u5b58\u7684\u65b9\u5f0f\u3002<\/p>\n<p>FireDAC\u6570\u636e\u4fdd\u5b58\uff0c\u5927\u81f4\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p>\n<p>\u201cTFDDataSet.InternalSaveToStorage\u201d<\/p>\n<p>-\u300b\u201cTFDDatSManager.InternalSaveToStorage&#8221;<\/p>\n<p>-\u300b\u201cTFDDatSTable.InternalSaveToStorage&#8221;<\/p>\n<p>&#8211; \u300b\u201cTFDDatSColumnList.InternalSaveToStorage&#8221;<\/p>\n<p>&#8211; \u300b\u201cTFDDatSTableRowList.InternalSaveToStorage&#8221;<\/p>\n<p>\u6839\u636e\u4f20\u5165\u4e0d\u540c\u7684Storage\u6765\u83b7\u53d6\u4e0d\u540c\u7684\u683c\u5f0f\u7684Storage\uff0c\u901a\u8fc7Storage\u7684Write\u548cRead\u76f8\u5173\u65b9\u6cd5\uff0c\u6765\u4fdd\u5b58\u6570\u636e\u6240\u6709\u7684\u6570\u636e\u548c\u53c2\u6570\u3002<\/p>\n<p>\u90a3\u6211\u4eec\u7528QJson\uff0c\u4e5f\u662f\u53ef\u4ee5\u501f\u9274\u4e0a\u9762\u7684\u65b9\u5f0f\u6765\u4fdd\u5b58\u6570\u636e\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u6211\u7684\u65b9\u6cd5\u5982\u4e0b\uff1a<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"font:arial lang:delphi decode:true\">procedure SaveToJSON(Node: TQJson);\r\n\r\n  procedure WriteValue(ANode: TQJson; const APropName: String; APropIndex: Word;\r\n    ADataType: TFDDataType; ABuff: Pointer; ALen: LongWord); overload;\r\n  const\r\n    CDateTimeISO8601Format: String = '%.4d%.2d%.2dT%.2d%.2d%.2d';\r\n    CTimeFormat: String = '%.2d%.2d%.2d';\r\n    CDateFormat: String = '%.4d%.2d%.2d';\r\n  var\r\n    sVal: String;\r\n    sSign: String;\r\n    iLen: Integer;\r\n    y, mo, d, h, mi, se, ms: Word;\r\n    dt: TDateTime;\r\n    pTS: PSQLTimeStamp;\r\n    pInt: PFDSQLTimeInterval;\r\n    rTS: TSQLTimeStamp;\r\n    pDest: PChar;\r\n    aFixed: array [0 .. C_FD_MaxFixedSize] of Char;\r\n  begin\r\n    if ABuff = nil then\r\n      Exit;\r\n    pDest := @aFixed[0];\r\n    iLen := SizeOf(aFixed) div SizeOf(Char);\r\n    case ADataType of\r\n      dtObject,\r\n        dtRowSetRef,\r\n        dtCursorRef,\r\n        dtRowRef,\r\n        dtArrayRef,\r\n        dtParentRowRef:\r\n        ;\r\n      dtWideMemo,\r\n        dtWideHMemo,\r\n        dtXML,\r\n        dtWideString:\r\n\r\n        ANode.Add(APropName, PWideChar(ABuff), jdtString);\r\n      dtMemo,\r\n        dtHMemo,\r\n        dtAnsiString:\r\n        begin\r\n          pDest := nil;\r\n          iLen := FQuery.Encoder.Decode(ABuff, ALen, Pointer(pDest), ecUTF16, ecANSI);\r\n          ANode.Add(APropName, pDest, jdtString);\r\n        end;\r\n      dtByteString,\r\n        dtBlob,\r\n        dtHBlob,\r\n        dtHBFile:\r\n        ANode.Add(APropName, FDBin2Hex(ABuff, ALen), jdtString);\r\n      dtBoolean:\r\n        ANode.Add(APropName, PWord(ABuff)^ &lt;&gt; 0);\r\n      dtSByte:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(ShortInt), pDest, iLen, False, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtInt16:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(SmallInt), pDest, iLen, False, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtInt32:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(Integer), pDest, iLen, False, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtInt64:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(Int64), pDest, iLen, False, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtByte:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(Byte), pDest, iLen, True, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtUInt16:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(Word), pDest, iLen, True, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtUInt32:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(LongWord), pDest, iLen, True, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtUInt64:\r\n        begin\r\n          FDInt2Str(ABuff, SizeOf(UInt64), pDest, iLen, True, 0);\r\n          ANode.Add(APropName, pDest, jdtInteger);\r\n        end;\r\n      dtSingle:\r\n        ANode.Add(APropName, FDFloat2Str(PSingle(ABuff)^, '.'), jdtFloat);\r\n      dtDouble:\r\n        ANode.Add(APropName, FDFloat2Str(PDouble(ABuff)^, '.'), jdtFloat);\r\n      dtExtended:\r\n        ANode.Add(APropName, FDFloat2Str(PExtended(ABuff)^, '.'), jdtFloat);\r\n      dtCurrency:\r\n        ANode.Add(APropName, FDFloat2Str(PCurrency(ABuff)^, '.'), jdtFloat);\r\n      dtBCD,\r\n        dtFmtBCD:\r\n        begin\r\n          FDBCD2Str(pDest, iLen, PBcd(ABuff)^, '.');\r\n          ANode.Add(APropName, pDest, jdtFloat);\r\n        end;\r\n      dtDateTime:\r\n        begin\r\n          dt := TimeStampToDateTime(MSecsToTimeStamp(PDateTimeRec(ABuff)^.DateTime));\r\n          DecodeDate(dt, y, mo, d);\r\n          DecodeTime(dt, h, mi, se, ms);\r\n          iLen := WideFormatBuf(pDest^, iLen, Pointer(CDateTimeISO8601Format)^,\r\n            Length(CDateTimeISO8601Format), [y, mo, d, h, mi, se], FormatSettings);\r\n          ANode.Add(APropName, pDest, jdtDateTime);\r\n        end;\r\n      dtDateTimeStamp:\r\n        begin\r\n          pTS := PSQLTimeStamp(ABuff);\r\n          iLen := WideFormatBuf(pDest^, iLen, Pointer(CDateTimeISO8601Format)^,\r\n            Length(CDateTimeISO8601Format), [pTS^.Year, pTS^.Month, pTS^.Day, pTS^.Hour,\r\n            pTS^.Minute, pTS^.Second], FormatSettings);\r\n          ANode.Add(APropName, pDest, jdtString);\r\n        end;\r\n      dtTimeIntervalFull,\r\n        dtTimeIntervalYM,\r\n        dtTimeIntervalDS:\r\n        begin\r\n          pInt := PFDSQLTimeInterval(ABuff);\r\n          if pInt^.Sign &lt; 0 then\r\n            sSign := '-'\r\n          else\r\n            sSign := '';\r\n          case pInt^.Kind of\r\n            itYear:\r\n              sVal := Format('%sP%uY', [sSign, pInt^.Years]);\r\n            itMonth:\r\n              sVal := Format('%sP%uM', [sSign, pInt^.Months]);\r\n            itDay:\r\n              sVal := Format('%sP%uD', [sSign, pInt^.Days]);\r\n            itHour:\r\n              sVal := Format('%sT%uH', [sSign, pInt^.Hours]);\r\n            itMinute:\r\n              sVal := Format('%sT%uM', [sSign, pInt^.Minutes]);\r\n            itSecond:\r\n              sVal := Format('%sT%uS%uF', [sSign, pInt^.Seconds, pInt^.Fractions]);\r\n            itYear2Month:\r\n              sVal := Format('%sP%uY%uM', [sSign, pInt^.Years, pInt^.Months]);\r\n            itDay2Hour:\r\n              sVal := Format('%sP%uDT%uH', [sSign, pInt^.Days, pInt^.Hours]);\r\n            itDay2Minute:\r\n              sVal := Format('%sP%uDT%uH%uM', [sSign, pInt^.Days, pInt^.Hours, pInt^.Minutes]);\r\n            itDay2Second:\r\n              sVal := Format('%sP%uDT%uH%uM%uS%uF', [sSign, pInt^.Days, pInt^.Hours, pInt^.Minutes, pInt^.Seconds, pInt^.Fractions]);\r\n            itHour2Minute:\r\n              sVal := Format('%sT%uH%uM', [sSign, pInt^.Hours, pInt^.Minutes]);\r\n            itHour2Second:\r\n              sVal := Format('%sT%uH%uM%uS%uF', [sSign, pInt^.Hours, pInt^.Minutes, pInt^.Seconds, pInt^.Fractions]);\r\n            itMinute2Second:\r\n              sVal := Format('%sT%uM%uS%uF', [sSign, pInt^.Minutes, pInt^.Seconds, pInt^.Fractions]);\r\n          end;\r\n          ANode.Add(APropName, sVal, jdtString);\r\n        end;\r\n      dtTime:\r\n        begin\r\n          rTS := FDTime2SQLTimeStamp(PLongint(ABuff)^);\r\n          iLen := WideFormatBuf(pDest^, iLen, Pointer(CTimeFormat)^,\r\n            Length(CTimeFormat), [rTS.Hour, rTS.Minute, rTS.Second], FormatSettings);\r\n          ANode.Add(APropName, pDest, jdtDateTime);\r\n        end;\r\n      dtDate:\r\n        begin\r\n          rTS := FDDate2SQLTimeStamp(PLongint(ABuff)^);\r\n          iLen := WideFormatBuf(pDest^, iLen, Pointer(CDateFormat)^,\r\n            Length(CDateFormat), [rTS.Year, rTS.Month, rTS.Day], FormatSettings);\r\n          ANode.Add(APropName, pDest, jdtDateTime);\r\n        end;\r\n      dtGUID:\r\n        ANode.Add(APropName, GUIDToString(PGUID(ABuff)^), jdtString);\r\n    end;\r\n  end;\r\n\r\nvar\r\n\r\n  lNode, lRowsNode, lRowNode: TQJson;\r\n\r\n  i, j: Integer;\r\n  oRows: TFDDatSTableRowList;\r\n  oRow: TFDDatSRow;\r\n  oCols: TFDDatSColumnList;\r\n  oCol: TFDDatSColumn;\r\n\r\n  pBuff: Pointer;\r\n  iLen: LongWord;\r\nbegin\r\n  if FQuery &lt;&gt; nil then\r\n  begin\r\n    oRows := FQuery.Table.Rows;\r\n    oCols := FQuery.Table.Columns;\r\n\r\n    lNode := Node.Add('data', jdtObject);\r\n    lRowsNode := lNode.AddArray('rows');\r\n\r\n    for i := 0 to oRows.Count - 1 do\r\n    begin\r\n      oRow := oRows.ItemsI[i];\r\n      lRowNode := lRowsNode.Add();\r\n      for j := 0 to oCols.Count - 1 do\r\n      begin\r\n        pBuff := nil;\r\n        iLen := 0;\r\n        oCol := oCols.ItemsI[j];\r\n\r\n        oRow.GetData(j, rvDefault, pBuff, 0, iLen, False);\r\n        WriteValue(lRowNode, oCol.Name, j, oCol.DataType, pBuff, iLen);\r\n      end;\r\n    end;\r\n  end;\r\nend;<\/pre>\n<p>&nbsp;<\/p>\n<p>\u8fd9\u6837\u7684\u4fdd\u5b58\u65b9\u5f0f\uff0c\u6eda\u52a8\u7684\u6548\u7387\u4e0a\u6bd4\u3002\u4f60\u4eec\u81ea\u5df2\u6d4b\u8bd5\u4e00\u4e0b\u5c31\u77e5\u9053\u4e86\uff0c\u6211\u4e0d\u8bf4\u4e86\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u6211\u505a\u8fc7\u5bf9\u6bd4\uff0c\u8fd9\u6837\u4fdd\u5b58\u6548\u7387\u7684\u5dee\u8ddd\u662f\u5728QJson\u7684SaveToStream\u8fd9\u4e00\u6b65\u3002\u671f\u5f85swish\u7684QDAC3.0\u3002<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9996\u5148\u6211\u4eec\u6765\u770bFireDAC\u7684\u6570\u636e\u5bf9\u8c61\uff0c\u770b [&hellip;]<\/p>\n","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[8],"tags":[],"class_list":["post-1355","post","type-post","status-publish","format-standard","hentry","category-delphi"],"views":9866,"_links":{"self":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/1355","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1355"}],"version-history":[{"count":6,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/1355\/revisions"}],"predecessor-version":[{"id":1371,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=\/wp\/v2\/posts\/1355\/revisions\/1371"}],"wp:attachment":[{"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1355"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1355"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qdac.cc\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1355"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}