在 Microsoft Dynamics 中使用 executeQueryWithParameters 加入 x++/sql 语句时如何获得正确的语法?
How can I get the syntax correct when using executeQueryWithParameters to join an x++/sql statement in Microsoft Dynamics?
我目前正在查看 Dynamics 365 for Finance and Operations Development Cookbook - Fourth Edition 中“Executing a direct SQL statement”的示例。
在文中,使用以下填充str sqlStatement
:
sqlStatement = 'SELECT %1, %2 FROM %3 ' +
'JOIN %4 ON %3.%5 = %4.%6 ' +
'WHERE %7 = %9 AND %8 = %10';
sqlStatement = strFmt(
sqlStatement,
fldAccountNum.name(DbBackend::Sql),
fldName.name(DbBackend::Sql),
tblVendTable.name(DbBackend::Sql),
tblDirPartyTable.name(DbBackend::Sql),
fldParty.name(DbBackend::Sql),
fldRecId.name(DbBackend::Sql),
fldDataAreaId.name(DbBackend::Sql),
fldBlocked.name(DbBackend::Sql),
sqlSystem.sqlLiteral(curext(), true),
sqlSystem.sqlLiteral(CustVendorBlocked::No, true));
用
执行
resultSet = statement.executeQuery(sqlStatement);
但是,Visual Studio 警告我这已经过时了,所以我想用 statement.executeQueryWithParameters(sqlStatement, valueByKeyMap);
替换它
...当然,要做到这一点,我需要创建地图,这似乎没有我预期的那么简单。
目前我已经分配了这个:
str sqlStatement = @'SELECT @accountNumberField, @nameField' +
' FROM @vendTable v' +
' JOIN @partyTable p' +
' ON (@vendTable.@partyField = @partyTable.@recId)' +
' WHERE (@dataAreaIdField = @dataArea)' +
' AND (@blockedField = @notBlocked)';
然后像这样填充地图:
Map valueByKeyMap = SqlParams::create();
DictField accountNumberField = new DictField(tableNum(VendTable), fieldNum(VendTable, AccountNum));
valueByKeyMap.add('accountNumberField', accountNumberField.name(DbBackend::Sql));
DictField nameField = new DictField(tableNum(DirPartyTable), fieldNum(DirPartyTable, Name));
valueByKeyMap.add('nameField', nameField.name(DbBackend::Sql));
DictTable vendTableDictionary = new DictTable(tableNum(VendTable));
valueByKeyMap.add('vendTable', vendTableDictionary.name(DbBackend::Sql));
DictTable partyTableDictionary = new DictTable(tableNum(DirPartyTable));
valueByKeyMap.add('partyTable', partyTableDictionary.name(DbBackend::Sql));
DictField partyField = new DictField(tableNum(VendTable), fieldNum(VendTable, Party));
valueByKeyMap.add('partyField', partyField.name(DbBackend::Sql));
DictField recId = new DictField(tableNum(DirPartyTable), fieldNum(DirPartyTable, RecId));
valueByKeyMap.add('recId', recId.name(DbBackend::Sql));
DictField dataAreaIdField = new DictField(tableNum(VendTable), fieldNum(VendTable, DataAreaId));
valueByKeyMap.add('dataAreaIdField', dataAreaIdField.name(DbBackend::Sql));
DictField blockedField = new DictField(tableNum(VendTable), fieldNum(VendTable, Blocked));
valueByKeyMap.add('blockedField', blockedField.name(DbBackend::Sql));
valueByKeyMap.add('dataArea', curext());
valueByKeyMap.add('notBlocked', _sqlSystem.sqlLiteral(CustVendorBlocked::No, true));
然而,当代码执行时,我得到 [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '@partyField'.
预期的语法是什么,我应该如何解决这个问题?
我不熟悉 MS 动态编程。使用 C#
字符串插值,有点
String accountNumberField = ...;
String nameField = ... ;
//... other variables for the string interpolation below
String statement =$"SELECT {accountNumberField}, {nameField}
FROM {vendTable} v
JOIN {partyTable} p
ON (v.{partyField} = p.{recId})
WHERE ({dataAreaIdField} = @dataArea)
AND ({blockedField} = @notBlocked)";
// Create and set values only Sql parameters `@dataArea` and `@notBlocked` with your tool here. Assotiate them with sqlStatement which text is statement
// ...
resultSet = statement.executeQuery(sqlStatement);
我目前正在查看 Dynamics 365 for Finance and Operations Development Cookbook - Fourth Edition 中“Executing a direct SQL statement”的示例。
在文中,使用以下填充str sqlStatement
:
sqlStatement = 'SELECT %1, %2 FROM %3 ' +
'JOIN %4 ON %3.%5 = %4.%6 ' +
'WHERE %7 = %9 AND %8 = %10';
sqlStatement = strFmt(
sqlStatement,
fldAccountNum.name(DbBackend::Sql),
fldName.name(DbBackend::Sql),
tblVendTable.name(DbBackend::Sql),
tblDirPartyTable.name(DbBackend::Sql),
fldParty.name(DbBackend::Sql),
fldRecId.name(DbBackend::Sql),
fldDataAreaId.name(DbBackend::Sql),
fldBlocked.name(DbBackend::Sql),
sqlSystem.sqlLiteral(curext(), true),
sqlSystem.sqlLiteral(CustVendorBlocked::No, true));
用
执行resultSet = statement.executeQuery(sqlStatement);
但是,Visual Studio 警告我这已经过时了,所以我想用 statement.executeQueryWithParameters(sqlStatement, valueByKeyMap);
...当然,要做到这一点,我需要创建地图,这似乎没有我预期的那么简单。
目前我已经分配了这个:
str sqlStatement = @'SELECT @accountNumberField, @nameField' +
' FROM @vendTable v' +
' JOIN @partyTable p' +
' ON (@vendTable.@partyField = @partyTable.@recId)' +
' WHERE (@dataAreaIdField = @dataArea)' +
' AND (@blockedField = @notBlocked)';
然后像这样填充地图:
Map valueByKeyMap = SqlParams::create();
DictField accountNumberField = new DictField(tableNum(VendTable), fieldNum(VendTable, AccountNum));
valueByKeyMap.add('accountNumberField', accountNumberField.name(DbBackend::Sql));
DictField nameField = new DictField(tableNum(DirPartyTable), fieldNum(DirPartyTable, Name));
valueByKeyMap.add('nameField', nameField.name(DbBackend::Sql));
DictTable vendTableDictionary = new DictTable(tableNum(VendTable));
valueByKeyMap.add('vendTable', vendTableDictionary.name(DbBackend::Sql));
DictTable partyTableDictionary = new DictTable(tableNum(DirPartyTable));
valueByKeyMap.add('partyTable', partyTableDictionary.name(DbBackend::Sql));
DictField partyField = new DictField(tableNum(VendTable), fieldNum(VendTable, Party));
valueByKeyMap.add('partyField', partyField.name(DbBackend::Sql));
DictField recId = new DictField(tableNum(DirPartyTable), fieldNum(DirPartyTable, RecId));
valueByKeyMap.add('recId', recId.name(DbBackend::Sql));
DictField dataAreaIdField = new DictField(tableNum(VendTable), fieldNum(VendTable, DataAreaId));
valueByKeyMap.add('dataAreaIdField', dataAreaIdField.name(DbBackend::Sql));
DictField blockedField = new DictField(tableNum(VendTable), fieldNum(VendTable, Blocked));
valueByKeyMap.add('blockedField', blockedField.name(DbBackend::Sql));
valueByKeyMap.add('dataArea', curext());
valueByKeyMap.add('notBlocked', _sqlSystem.sqlLiteral(CustVendorBlocked::No, true));
然而,当代码执行时,我得到 [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '@partyField'.
预期的语法是什么,我应该如何解决这个问题?
我不熟悉 MS 动态编程。使用 C# 字符串插值,有点
String accountNumberField = ...;
String nameField = ... ;
//... other variables for the string interpolation below
String statement =$"SELECT {accountNumberField}, {nameField}
FROM {vendTable} v
JOIN {partyTable} p
ON (v.{partyField} = p.{recId})
WHERE ({dataAreaIdField} = @dataArea)
AND ({blockedField} = @notBlocked)";
// Create and set values only Sql parameters `@dataArea` and `@notBlocked` with your tool here. Assotiate them with sqlStatement which text is statement
// ...
resultSet = statement.executeQuery(sqlStatement);