如何在定义的值区域中选择“插入”或“更新到”列

时间:2014-04-19 15:05:27

标签: firebird

我有一个包含不同值的列,假设它是一列中的子数据库。

例如:value1:abc,value2:123,value3:xyz。

如何使用select读出单个值以及如何将它们写回来?

例如,我想读出value2:123并想要写回value2:789

问题是如何定义Select和Update Firebird SQL顺序。

1 个答案:

答案 0 :(得分:2)

您可以通过UDF执行此操作。 我不知道你喜欢哪种语言 - 所以这是Delphi的一个例子。您必须将库复制到firebird的udf目录并使用

在数据库中声明这些函数
DECLARE EXTERNAL FUNCTION GETVALUE
    CSTRING(32767),
    CSTRING(32767)
RETURNS CSTRING(32767) FREE_IT
ENTRY_POINT 'GetValue' MODULE_NAME 'Project1';
DECLARE EXTERNAL FUNCTION SETVALUE
    CSTRING(32767),
    CSTRING(32767),
    CSTRING(32767)
RETURNS CSTRING(32767) FREE_IT
ENTRY_POINT 'SetValue' MODULE_NAME 'Project1';

然后你可以在SQL语句中使用它:

SELECT GETVALUE(valuescolumn, 'Value1') from valuestable;

UPDATE valuestable SET valuescolum = SETVALUE(valuescolumn, 'Value1', 'NewValue')

我在没有测试的情况下将其写下来 - 所以我不确定我是否有任何语法错误。

library Project1;

uses
  System.SysUtils,
  System.Classes;

{$IFDEF ib_util}
function ib_util_malloc(l: integer): pointer; cdecl; external 'ib_util.dll';
{$ELSE}
function malloc(Bytes: Integer): Pointer; cdecl; external 'msvcrt.dll';
{$ENDIF}

function MemAlloc(Bytes: Integer): Pointer;
begin
{$IFDEF ib_util}
  Result:= ib_util_malloc(Bytes);
{$ELSE}
  Result:= malloc(Bytes);
{$ENDIF}
end;

function MakeResult(aString: string): PChar;
var
  fLength: Integer;
begin
  fLength:= Length(aString);
  Result:= MemAlloc(fLength+1);
  if fLength > 0 then
    Move(aString[1], Result[0], fLength);
  Result[fLength]:= #0;
end;

function GetValue(aValues, aValueName: PChar): PChar; cdecl; export;
var
  ValueList: TStringList;
  TempResult: string;
begin
  ValueList := TStringList.Create;
  try
    try
      ValueList.Text := aValues;
      ValueList.NameValueSeparator := ':';
      TempResult := ValueList.Values[aValueName];
      Result:= MakeResult(TempResult);
    except
      Result:= nil;
    end;
  finally
    ValueList.Free;
  end;
end;

function SetValue(aValues, aValueName, aValue: PChar): PChar; cdecl; export;
var
  ValueList: TStringList;
begin
  ValueList := TStringList.Create;
  try
    try
      ValueList.Text := aValues;
      ValueList.NameValueSeparator := ':';
      ValueList.Values[aValueName] := aValue;
      Result:= MakeResult(ValueList.Text);
    except
      Result:= nil;
    end;
  finally
    ValueList.Free;
  end;
end;

begin
end.