我目前正在开发一个 C# 解决方案,用于将数据库表从 Oracle 复制到 PostgreSQL。除了一件事之外,一切都运转良好。当我开始复制其中一个字段中包含 sql 语句的表时,由于有两个单引号背靠背,它会崩溃。 SQL 语句必须保留在表中,因为它被用于使另一个程序与数据库无关。
有没有办法编写以下 SQL,但没有两个单引号背靠背,如行尾附近“TRUE”值附近所示。我还在下面添加了我的代码,以展示该语句是如何在 C# 中构建的。该列在 Oracle 中是 varchar2,在 PostgreSQL 中是 TEXT 列。
编辑:显示的 sql 示例是我的 C# 代码生成的实际 INSERT 语句,然后该语句将在 postgresql 数据库上运行以向表中添加记录。它将用于插入文本字段等,其中包含字符串形式的 sql 语句。
INSERT INTO SQL_FACTORY_TEST (SQL_FACTORY_TEST_ID,SQL_FACTORY_DIALECT,SQL_FACTORY_QUERY_NAME,SQL_FACTORY_SQL_COMMAND,USER_NAME)
VALUES (21, 'ORACLE', 'GET_CLUSTERS', 'SELECT CLUSTER_ID, NUM_POINTS, FEATURE_PK, A.CELL_CENTROID.SDO_POINT.X, A.CELL_CENTROID.SDO_POINT.Y, A.CLUSTER_CENTROID.SDO_POINT.X, A.CLUSTER_CENTROID.SDO_POINT.Y, TO_CHAR (A.CLUSTER_EXTENT.GET_WKT ()), TO_CHAR (A.CELL_GEOM.GET_WKT ()), A.CLUSTER_EXTENT.SDO_SRID FROM (SELECT CLUSTER_ID, NUM_POINTS, FEATURE_PK, SDO_CS.transform (CLUSTER_CENTROID, 4326) cluster_centroid, CLUSTER_EXTENT, SDO_CS.transform (CELL_CENTROID, 4326) cell_centroid, CELL_GEOM FROM :0) a where sdo_filter( A.CELL_GEOM, SDO_CS.transform(mdsys.sdo_geometry(2003, :1, NULL, mdsys.sdo_elem_info_array(1,1003,3),mdsys.sdo_ordinate_array(:2, :3, :4, :5)),81989)) = 'TRUE'', 'PUBLIC')
代码示例:
oleDataBaseConnection.OleExecutePureSqlQuery("SELECT * FROM " + tableName);
if (oleDataBaseConnection.HasRows())
{
while (oleDataBaseConnection.NextRecord())
{
Dictionary<string, string> postgreSQLQueries = TypeConversion.GetQueryDictionary("POSTGRESQL");
string postgreSQLInsertQuery;
postgreSQLQueries.TryGetValue("INSERT", out postgreSQLInsertQuery);
postgreSQLInsertQuery = postgreSQLInsertQuery.Replace("{0}", tableName);
StringBuilder postgresQuery = new StringBuilder();
postgresQuery.Append(postgreSQLInsertQuery);
postgresQuery.Append("(");
int columnCounter = 0;
//add a column parameter to query for each of our columns
foreach (KeyValuePair<string, string> t in columnData)
{
postgresQuery.Append(t.Key + ",");
columnCounter++;
}
postgresQuery = postgresQuery.Remove(postgresQuery.Length - 1, 1);
postgresQuery.Append(") ");
postgresQuery.Append("VALUES (");
//Loop through values and
for (int i = 0; i < columnCounter; i++)
{
string[] foo = new string[columnData.Count];
columnData.Values.CopyTo(foo, 0);
if (foo[i].ToUpper() == "TEXT")
{
postgresQuery.Append("'" + oleDataBaseConnection.GetFieldById(i) + "', ");
}
else
{
postgresQuery.Append(oleDataBaseConnection.GetFieldById(i) + ", ");
}
}
postgresQuery = postgresQuery.Remove(postgresQuery.Length - 2, 2);
postgresQuery.Append(") ");
postgresSQLDBConnection.PostgreSQLExecutePureSqlNonQuery(postgresQuery.ToString());
}
}
最佳答案
最好的解决方案是使用PreparedStatement,不直接传递文字。我不懂 C#,所以我无法给你一个例子。
但是,如果您必须保留这样的语句,则可以在 PostgreSQL 中使用“dollar quoted ”字符串文字。
INSERT INTO SQL_FACTORY_TEST (SQL_FACTORY_TEST_ID,SQL_FACTORY_DIALECT,SQL_FACTORY_QUERY_NAME,SQL_FACTORY_SQL_COMMAND,USER_NAME)
VALUES (21, 'ORACLE', 'GET_CLUSTERS', $$ ...... 'TRUE'$$, 'PUBLIC')
$$ 替换文字周围的单引号。如果您的值有可能包含 $$
您还可以为其添加一些唯一标识符,例如
$42$String with embedded single quotes ''' and two $$ dollar characters$42$
关于c# - 以编程方式插入字段值为 SQL 语句的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9905004/