📄 ibsql.pas
字号:
IBAlloc(xvar.FXSQLVAR^.sqlind, 0, SizeOf(Short));
end
else
begin
xvar.FXSQLVAR^.sqltype := xvar.FXSQLVAR^.sqltype and (not 1);
ReallocMem(xvar.FXSQLVAR^.sqlind, 0);
end;
end;
end;
end;
procedure TIBXSQLVAR.Clear;
begin
IsNull := true;
end;
procedure TIBXSQLVAR.SetAsTrimString(const Value: String);
begin
SetAsString(TrimRight(Value));
end;
function TIBXSQLVAR.GetAsTrimString: String;
begin
Result := TrimRight(GetAsString);
end;
{ TIBXSQLDA }
constructor TIBXSQLDA.Create(Query: TIBSQL);
begin
inherited Create;
FSQL := Query;
FNames := TStringList.Create;
FSize := 0;
FUniqueRelationName := '';
end;
destructor TIBXSQLDA.Destroy;
var
i: Integer;
begin
FNames.Free;
if FXSQLDA <> nil then
begin
for i := 0 to FSize - 1 do
begin
FreeMem(FXSQLVARs[i].FXSQLVAR^.sqldata);
FreeMem(FXSQLVARs[i].FXSQLVAR^.sqlind);
FXSQLVARs[i].Free ;
end;
FreeMem(FXSQLDA);
FXSQLDA := nil;
FXSQLVARs := nil;
end;
inherited Destroy;
end;
procedure TIBXSQLDA.AddName(FieldName: String; Idx: Integer);
var
fn: String;
begin
fn := FormatIdentifierValue(FSQL.Database.SQLDialect, FieldName);
while FNames.Count <= Idx do
FNames.Add('');
FNames[Idx] := fn;
FXSQLVARs[Idx].FName := fn;
FXSQLVARs[Idx].FIndex := Idx;
end;
function TIBXSQLDA.GetModified: Boolean;
var
i: Integer;
begin
result := False;
for i := 0 to FCount - 1 do
if FXSQLVARs[i].Modified then
begin
result := True;
exit;
end;
end;
function TIBXSQLDA.GetNames: String;
begin
result := FNames.Text;
end;
function TIBXSQLDA.GetRecordSize: Integer;
begin
result := SizeOf(TIBXSQLDA) + XSQLDA_LENGTH(FSize);
end;
function TIBXSQLDA.GetXSQLDA: PXSQLDA;
begin
result := FXSQLDA;
end;
function TIBXSQLDA.GetXSQLVAR(Idx: Integer): TIBXSQLVAR;
begin
if (Idx < 0) or (Idx >= FCount) then
IBError(ibxeXSQLDAIndexOutOfRange, [nil]);
result := FXSQLVARs[Idx]
end;
function TIBXSQLDA.ByName(Idx: String): TIBXSQLVAR;
begin
result := GetXSQLVARByName(Idx);
if result = nil then
IBError(ibxeFieldNotFound, [Idx]);
end;
function TIBXSQLDA.GetXSQLVARByName(Idx: String): TIBXSQLVAR;
var
s: String;
i, Cnt: Integer;
begin
s := FormatIdentifierValue(FSQL.Database.SQLDialect, Idx);
i := 0;
Cnt := FNames.Count;
while (i < Cnt) and (FNames[i] <> s) do Inc(i);
if i = Cnt then
result := nil
else
result := GetXSQLVAR(i);
end;
procedure TIBXSQLDA.Initialize;
var
i, j, j_len: Integer;
NamesWereEmpty: Boolean;
st: String;
bUnique: Boolean;
begin
bUnique := True;
NamesWereEmpty := (FNames.Count = 0);
if FXSQLDA <> nil then
begin
for i := 0 to FCount - 1 do
begin
with FXSQLVARs[i].Data^ do
begin
if bUnique and (String(relname) <> '') then
begin
if FUniqueRelationName = '' then
FUniqueRelationName := String(relname)
else
if String(relname) <> FUniqueRelationName then
begin
FUniqueRelationName := '';
bUnique := False;
end;
end;
if NamesWereEmpty then
begin
st := String(aliasname);
if st = '' then
begin
st := 'F_'; {do not localize}
aliasname_length := 2;
j := 1; j_len := 1;
StrPCopy(aliasname, st + IntToStr(j));
end
else
begin
StrPCopy(aliasname, st);
j := 0; j_len := 0;
end;
while GetXSQLVARByName(String(aliasname)) <> nil do
begin
Inc(j); j_len := Length(IntToStr(j));
if j_len + aliasname_length > 31 then
StrPCopy(aliasname,
Copy(st, 1, 31 - j_len) +
IntToStr(j))
else
StrPCopy(aliasname, st + IntToStr(j));
end;
Inc(aliasname_length, j_len);
AddName(String(aliasname), i);
end;
if (sqltype and (not 1) = SQL_TEXT) or
(sqltype and (not 1) = SQL_VARYING) then
FXSQLVARs[i].FMaxLen := sqllen
else
FXSQLVARs[i].FMaxLen := 0;
case sqltype and (not 1) of
SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP,
SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT,
SQL_LONG, SQL_INT64, SQL_DOUBLE, SQL_FLOAT, SQL_D_FLOAT:
begin
if (sqllen = 0) then
{ Make sure you get a valid pointer anyway
select '' from foo }
IBAlloc(sqldata, 0, 1)
else
IBAlloc(sqldata, 0, sqllen)
end;
SQL_VARYING:
begin
IBAlloc(sqldata, 0, sqllen + 2);
end;
else
IBError(ibxeUnknownSQLDataType, [sqltype and (not 1)])
end;
if (sqltype and 1 = 1) then
IBAlloc(sqlind, 0, SizeOf(Short))
else
if (sqlind <> nil) then
ReallocMem(sqlind, 0);
end;
end;
end;
end;
procedure TIBXSQLDA.SetCount(Value: Integer);
var
i, OldSize: Integer;
p : PXSQLVAR;
begin
FNames.Clear;
FCount := Value;
if FCount = 0 then
FUniqueRelationName := ''
else
begin
if FSize > 0 then
OldSize := XSQLDA_LENGTH(FSize)
else
OldSize := 0;
if FCount > FSize then
begin
IBAlloc(FXSQLDA, OldSize, XSQLDA_LENGTH(FCount));
SetLength(FXSQLVARs, FCount);
FXSQLDA^.version := SQLDA_VERSION1;
p := @FXSQLDA^.sqlvar[0];
for i := 0 to FCount - 1 do
begin
if i >= FSize then
FXSQLVARs[i] := TIBXSQLVAR.Create(self, FSQL);
FXSQLVARs[i].FXSQLVAR := p;
p := Pointer(PChar(p) + sizeof(FXSQLDA^.sqlvar));
end;
FSize := FCount;
end;
if FSize > 0 then
begin
FXSQLDA^.sqln := Value;
FXSQLDA^.sqld := Value;
end;
end;
end;
{ TIBOutputDelimitedFile }
destructor TIBOutputDelimitedFile.Destroy;
begin
FFile.Free;
inherited Destroy;
end;
procedure TIBOutputDelimitedFile.ReadyFile;
var
i: Integer;
st: string;
begin
if FColDelimiter = '' then
FColDelimiter := TAB;
if FRowDelimiter = '' then
FRowDelimiter := CRLF;
FFile := TFileStream.Create(FFilename, fmCreate or fmShareDenyWrite);
if FOutputTitles then
begin
for i := 0 to Columns.Count - 1 do
if i = 0 then
st := string(Columns[i].Data^.aliasname)
else
st := st + FColDelimiter + string(Columns[i].Data^.aliasname);
st := st + FRowDelimiter;
FFile.Write(st[1], Length(st));
end;
end;
function TIBOutputDelimitedFile.WriteColumns: Boolean;
var
i: Integer;
BytesWritten: DWORD;
st: string;
begin
result := False;
if Assigned(FFile) then
begin
st := '';
for i := 0 to Columns.Count - 1 do
begin
if i > 0 then
st := st + FColDelimiter;
st := st + StripString(Columns[i].AsString, FColDelimiter + FRowDelimiter);
end;
st := st + FRowDelimiter;
BytesWritten := FFile.Write(st[1], Length(st));
if BytesWritten = DWORD(Length(st)) then
result := True;
end
end;
{ TIBInputDelimitedFile }
destructor TIBInputDelimitedFile.Destroy;
begin
FFile.Free;
inherited Destroy;
end;
function TIBInputDelimitedFile.GetColumn(var Col: string): Integer;
var
c: Char;
BytesRead: Integer;
procedure ReadInput;
begin
if FLookAhead <> NULL_TERMINATOR then
begin
c := FLookAhead;
BytesRead := 1;
FLookAhead := NULL_TERMINATOR;
end else
BytesRead := FFile.Read(c, 1);
end;
procedure CheckCRLF(Delimiter: string);
begin
if (c = CR) and (Pos(LF, Delimiter) > 0) then {mbcs ok}
begin
BytesRead := FFile.Read(c, 1);
if (BytesRead = 1) and (c <> #10) then
FLookAhead := c
end;
end;
begin
Col := '';
result := 0;
ReadInput;
while BytesRead <> 0 do begin
if Pos(c, FColDelimiter) > 0 then {mbcs ok}
begin
CheckCRLF(FColDelimiter);
result := 1;
break;
end else if Pos(c, FRowDelimiter) > 0 then {mbcs ok}
begin
CheckCRLF(FRowDelimiter);
result := 2;
break;
end else
Col := Col + c;
ReadInput;
end;
end;
function TIBInputDelimitedFile.ReadParameters: Boolean;
var
i, curcol: Integer;
Col: string;
begin
result := False;
if not FEOF then
begin
curcol := 0;
repeat
i := GetColumn(Col);
if (i = 0) then
FEOF := True;
if (curcol < Params.Count) then
begin
try
if (Col = '') and
(ReadBlanksAsNull) then
Params[curcol].IsNull := True
else
Params[curcol].AsString := Col;
Inc(curcol);
except
on E: Exception do
begin
if not (FEOF and (curcol = Params.Count)) then
raise;
end;
end;
end;
until (FEOF) or (i = 2);
result := ((FEOF) and (curcol = Params.Count)) or
(not FEOF);
end;
end;
procedure TIBInputDelimitedFile.ReadyFile;
var
col : String;
curcol : Integer;
begin
if FColDelimiter = '' then
FColDelimiter := TAB;
if FRowDelimiter = '' then
FRowDelimiter := CRLF;
FLookAhead := NULL_TERMINATOR;
FEOF := False;
if FFile <> nil then
FFile.Free;
FFile := TFileStream.Create(FFilename, fmOpenRead or fmShareDenyWrite);
if FSkipTitles then
begin
curcol := 0;
while curcol < Params.Count do
begin
GetColumn(Col);
Inc(CurCol)
end;
end;
end;
{ TIBOutputRawFile }
destructor TIBOutputRawFile.Destroy;
begin
FFile.Free;
inherited Destroy;
end;
procedure TIBOutputRawFile.ReadyFile;
begin
if Assigned(FFile) then
FreeAndNil(FFile);
FFile := TFileStream.Create(Filename, fmCreate);
end;
function TIBOutputRawFile.WriteColumns: Boolean;
var
i: Integer;
BytesWritten: DWord;
begin
result := False;
if Assigned(FFile) then
begin
for i := 0 to Columns.Count - 1 do
begin
BytesWritten := FFile.Write(Columns[i].Data^.sqldata^, Columns[i].Data^.sqllen);
if BytesWritten <> DWORD(Columns[i].Data^.sqllen) then
exit;
end;
result := True;
end;
end;
{ TIBInputRawFile }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -