我正在编写 PHP 代码来更改 MySQL 数据库中 varchar 字段的默认值。为了使代码安全,我使用了一个准备好的语句,但由于某种原因,在这种特殊情况下似乎不可能让 PHP/MySQL 接受这一点,这是为什么呢?
(我使用的是 PHP 5.5.11)
这是使用准备好的语句的代码,它不起作用(mysqli_stmt_execute() 调用返回 null,并且该字段的默认值保持不变):
$new_field_default_value = 'test';
$field_modification_sql_command = "ALTER TABLE MyTable ALTER COLUMN MyColumn SET DEFAULT ?";
$stmt = mysqli_stmt_init($db_conn_handle);
mysqli_stmt_prepare($stmt, $field_modification_sql_command);
mysqli_stmt_bind_param($stmt, 's', $new_field_default_value);
$temp_db_res = mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
Run Code Online (Sandbox Code Playgroud)
这是使用连接和纯查询执行的(不安全)代码,它确实有效(mysqli_query() 调用返回 true,并且字段的默认值确实已更改):
$new_field_default_value = 'test';
$field_modification_sql_command = "ALTER TABLE MyTable ALTER COLUMN MyColumn SET DEFAULT '" . $new_field_default_value . "'";
$temp_db_res = mysqli_query($db_conn_handle, $field_modification_sql_command);
Run Code Online (Sandbox Code Playgroud)
谁能告诉我为什么在这里使用准备好的语句不起作用,以及我需要更改什么(如果可能的话?)以使其与准备好的语句一起使用?
在Delphi中,如果我有一个TValue
反映未知对象的实例,我该如何测试这个对象是否是任何类型的通用实例TEnumerable<>
(甚至更好,还有哪个特定的通用可枚举类型,例如TList<>
)?
注:我已经知道如何轻松地检查它的确切类型,即具有.BaseType
相应的财产TRttiType
的TValue
,造成例如TList<string>
,但我想测试比较,如果它是TList<>
的任何分项类型.
为了举例说明这个假设代码"IsAnyKindOfGenericEnumerable()"如何工作,这里有一些示例代码:
var
LContext : TRttiContext;
obj_1_rtti_value : TValue;
obj_2_rtti_value : TValue;
obj_3_rtti_value : TValue;
obj_1_rtti_type : TRttiType;
obj_2_rtti_type : TRttiType;
obj_3_rtti_type : TRttiType;
LContext := TRttiContext.Create();
{
...
obj_1_rtti_value is set to a TValue reflection of a TList<string> object here
obj_2_rtti_value is set to a TValue reflection of a plain TObject object here
obj_3_rtti_value is …
Run Code Online (Sandbox Code Playgroud) 如果我有一个包含带动态数组的字段的Delphi对象(包含例如字符串),如下所示:
TClassWithDynArrayField = class(TObject)
public
some_dyn_array : array of string;
end;
Run Code Online (Sandbox Code Playgroud)
当对象被销毁时,这个数组(和/或它的内容)会被自动释放/释放,还是我必须在对象的析构函数中以某种方式显式地完成它以避免内存泄漏或其他讨厌(垃圾中的崩溃)字符串和动态数组的收集器,或其他堆相关的代码等)?
如果答案是肯定的,那么一旦对象被销毁就会自动解除定位,同时也不会对字符串/动态数组垃圾收集产生任何不一致性,对于多级动态数组字段也是如此吗?例如这样:
TClassWithMultiLevelDynArrayField = class(TObject)
public
some_multi_level_dyn_array : array of array of string;
end;
Run Code Online (Sandbox Code Playgroud)
如果我改为使用定义这些数组(单级和/或多级)的"通用"方式(从我所听到的内部等同于"非通用"定义),答案是否会有任何不同动态数组,或不是吗?),如下:
TClassWithGenericMultiLevelDynArrayField = class(TObject)
public
some_generic_multi_level_dyn_array : TArray<TArray<string>>;
end;
Run Code Online (Sandbox Code Playgroud)
注意:对于所有这些示例,请假设其他代码将在对象被销毁之前随意填充所有级别的数组.
我之所以这么说是因为在对象(和动态分配的记录)中使用动态数组时,我经常会出现奇怪的访问冲突,并且在Delphi参考页面中有关于System.Finalize的一些半相关的讨论,看似区分动态数组的自动释放和例如字符串(即在基于Dispose的解除分配的情况下,但我认为它也可以应用于对象字段?),如下所示:
Finalize只应在Delphi代码中使用,其中动态分配的变量通过除Dispose过程之外的其他方式释放.动态数组永远不能使用Dispose过程释放,但可以通过将它们传递给Finalize来释放.
对于使用Dispose释放的全局变量,局部变量,对象和动态变量,编译器会生成代码,以在销毁实例时最终确定变量包含的所有长字符串,变量和接口.
如果动态变量满足以下两个条件,则需要调用Finalize以在变量可以被释放之前完成变量.
该变量通过除Dispose标准过程之外的其他方式释放(例如,使用FreeMem).
该变量包含长字符串,变体或接口,并非所有字符串都是空的或未分配的.
Finalize只是将所有长字符串设置为空,并将所有变量和接口设置为Unassigned,从而正确释放由长字符串和变体引用的任何内存.
请注意,在提到字符串的情况下,从未提及动态数组,并且在第一句中,动态数组被称为某种"手动"特殊情况?
因此,再次,Delphi对象字段中的动态数组将在对象被销毁时自动释放/释放,无论它们如何填充,例如字符串,并且无论它们是否是任意多个"级别深"(即内部的动态数组)动态数组),如上面的例子中所示?