Why does cloning a Doctrine entity with associations result in one extra INSERT? - sql

I have two related entities as follows:
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrders" table="app-name-here.rmtk_orders">
<indexes>
<index name="incoterms_id" columns="incoterms_id"/>
<index name="slots_id" columns="slots_id"/>
<index name="statuses_id" columns="statuses_id"/>
<index name="restaurant_users_id" columns="supplier_users_id"/>
<index name="origins_id" columns="origins_id"/>
<index name="payment_code" columns="payment_code"/>
<index name="currencies_iso_code" columns="currencies_iso_code"/>
<index name="domains_id" columns="domains_id"/>
<index name="dispatch_countries_iso_code_2" columns="dispatch_countries_iso_code_2"/>
<index name="subpayment_code" columns="subpayment_code"/>
<index name="language_code" columns="language_code"/>
<index name="users_id" columns="users_id"/>
</indexes>
<unique-constraints>
<unique-constraint name="orders_id2" columns="orders_id2,supplier_users_id,splitter"/>
</unique-constraints>
<id name="ordersId" type="integer" column="orders_id">
<generator strategy="IDENTITY"/>
</id>
<field name="ordersId2" type="string" column="orders_id2" length="36" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="username" type="string" column="username" length="256" nullable="false">
<options>
<option name="fixed"/>
</options>
</field>
<field name="createdTs" type="datetime" column="created_ts" nullable="false"/>
<field name="lastUpdate" type="datetime" column="last_update" nullable="true">
<options>
<option name="default">CURRENT_TIMESTAMP</option>
</options>
</field>
<field name="purchasedTs" type="datetime" column="purchased_ts" nullable="false"/>
<field name="remoteAddr" type="string" column="remote_addr" length="45" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="comments" type="text" column="comments" length="65535" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="channel" type="string" column="channel" length="16" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="hidden" type="boolean" column="hidden" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="version" type="string" column="version" length="3" nullable="true">
<options>
<option name="fixed">1</option>
</options>
</field>
<field name="userAgent" type="string" column="user_agent" length="256" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="backend" type="string" column="backend" length="32" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="referralCode" type="string" column="referral_code" length="6" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="hasSettlementsAttributed" type="boolean" column="has_settlements_attributed" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="totalVerified" type="boolean" column="total_verified" nullable="true"/>
<field name="totalVerificationTs" type="datetime" column="total_verification_ts" nullable="true"/>
<field name="nonViesTaxId" type="string" column="non_vies_tax_id" length="32" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="vatNumber" type="string" column="vat_number" length="16" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="vatNumberAppliedFromScVatTaxReport" type="boolean"
column="vat_number_applied_from_sc_vat_tax_report" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="vatNumberAppliedFromVidr" type="boolean" column="vat_number_applied_from_vidr" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="vatNumberViesValidity" type="boolean" column="vat_number_vies_validity" nullable="true"/>
<field name="vatNumberViesValidityVerificationTs" type="datetime"
column="vat_number_vies_validity_verification_ts" nullable="true"/>
<field name="exposedViaApi" type="boolean" column="exposed_via_api" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="acknowledged" type="boolean" column="acknowledged" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="notifyFailedAmazonInvoiceUploads" type="boolean" column="notify_failed_amazon_invoice_uploads"
nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="dispatchCountriesIsoCode2AppliedFromScVatTaxReport" type="boolean"
column="dispatch_countries_iso_code_2_applied_from_sc_vat_tax_report" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="dispatchCountriesIsoCode2AppliedFromVidr" type="boolean"
column="dispatch_countries_iso_code_2_applied_from_vidr" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="magentoEntityId" type="integer" column="magento_entity_id" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<field name="onbuyInternalReference" type="integer" column="onbuy_internal_reference" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<field name="invoiceUploadedSpApi" type="boolean" column="invoice_uploaded_sp_api" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="kauflandUploaded" type="integer" column="kaufland_uploaded" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<field name="piiPurged" type="boolean" column="pii_purged" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="billingYear" type="smallint" column="billing_year" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<field name="billingMonth" type="boolean" column="billing_month" nullable="true"/>
<field name="splitter" type="integer" column="splitter" nullable="false">
<options>
<option name="default">1</option>
</options>
</field>
<field name="dontInvoice" type="boolean" column="dont_invoice" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="kauflandIdOrderUnit" type="string" column="kaufland_id_order_unit" length="32" nullable="true">
<options>
<option name="default">0</option>
</options>
</field>
<many-to-one field="dispatchCountriesIsoCode2" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkCountries"
fetch="LAZY">
<join-columns>
<join-column name="dispatch_countries_iso_code_2" referenced-column-name="countries_iso_code_2"
nullable="true"/>
</join-columns>
</many-to-one>
<many-to-one field="currenciesIsoCode" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkCurrencies"
fetch="LAZY">
<join-columns>
<join-column name="currencies_iso_code" referenced-column-name="currencies_iso_code"/>
</join-columns>
</many-to-one>
<many-to-one field="languageCode" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkLanguages2"
fetch="LAZY">
<join-columns>
<join-column name="language_code" referenced-column-name="language_code"/>
</join-columns>
</many-to-one>
<many-to-one field="users" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkUsers" fetch="LAZY">
<join-columns>
<join-column name="users_id" referenced-column-name="users_id"/>
</join-columns>
</many-to-one>
<many-to-one field="slots" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkSlots" fetch="LAZY">
<join-columns>
<join-column name="slots_id" referenced-column-name="slots_id" nullable="true"/>
</join-columns>
</many-to-one>
<many-to-one field="incoterms" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkIncoterms" fetch="LAZY">
<join-columns>
<join-column name="incoterms_id" referenced-column-name="incoterms_id"/>
</join-columns>
</many-to-one>
<many-to-one field="supplierUsers" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkUsers" fetch="LAZY">
<join-columns>
<join-column name="supplier_users_id" referenced-column-name="users_id"/>
</join-columns>
</many-to-one>
<many-to-one field="paymentCode" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkPaymentMethods"
fetch="LAZY">
<join-columns>
<join-column name="payment_code" referenced-column-name="payment_code"/>
</join-columns>
</many-to-one>
<many-to-one field="origins" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrdersOrigins" fetch="LAZY">
<join-columns>
<join-column name="origins_id" referenced-column-name="origins_id"/>
</join-columns>
</many-to-one>
<many-to-one field="domains" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkDomains" fetch="LAZY">
<join-columns>
<join-column name="domains_id" referenced-column-name="domains_id"/>
</join-columns>
</many-to-one>
<many-to-one field="statuses" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkStatuses" fetch="LAZY">
<join-columns>
<join-column name="statuses_id" referenced-column-name="statuses_id"/>
</join-columns>
</many-to-one>
<many-to-one field="subpaymentCode" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkSubpaymentMethods"
fetch="LAZY">
<join-columns>
<join-column name="subpayment_code" referenced-column-name="subpayment_code"/>
</join-columns>
</many-to-one>
<many-to-many field="invoice" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkInvoices" fetch="LAZY">
<join-table name="app-name-here.rmtk_invoices">
<join-columns>
<join-column name="orders_id" referenced-column-name="orders_id"/>
</join-columns>
<inverse-join-columns>
<join-column name="invoices_id" referenced-column-name="invoices_id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-many field="addresses" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAddresses" fetch="LAZY">
<join-table name="app-name-here.rmtk_addresses">
<join-columns>
<join-column name="orders_id" referenced-column-name="orders_id"/>
</join-columns>
<inverse-join-columns>
<join-column name="addresses_id" referenced-column-name="addresses_id" />
</inverse-join-columns>
</join-table>
<cascade>
<cascade-all/>
</cascade>
</many-to-many>
<many-to-many field="tangibleItems" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrdersProducts"
fetch="LAZY">
<join-table name="app-name-here.rmtk_orders_products">
<join-columns>
<join-column name="orders_id" referenced-column-name="orders_id"/>
</join-columns>
<inverse-join-columns>
<join-column name="orders_products_id" referenced-column-name="orders_products_id"/>
</inverse-join-columns>
</join-table>
<cascade>
<cascade-all/>
</cascade>
</many-to-many>
<many-to-many field="nonTangibleItems"
target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrdersNontangibles" fetch="LAZY">
<join-table name="app-name-here.rmtk_orders_nontangibles">
<join-columns>
<join-column name="orders_id" referenced-column-name="orders_id"/>
</join-columns>
<inverse-join-columns>
<join-column name="on_id" referenced-column-name="on_id" unique="true"/>
</inverse-join-columns>
</join-table>
<cascade>
<cascade-all/>
</cascade>
</many-to-many>
<many-to-many field="mwsMfnRecords" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonOrdersMfn"
fetch="LAZY">
<join-table name="app-name-here.rmtk_amazon_orders_mfn">
<join-columns>
<join-column name="order_id" referenced-column-name="orders_id2"/>
</join-columns>
<inverse-join-columns>
<join-column name="id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-many field="mwsAfnRecords" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonOrdersAfn"
fetch="LAZY">
<join-table name="app-name-here.rmtk_amazon_orders_afn">
<join-columns>
<join-column name="amazon_order_id" referenced-column-name="orders_id2"/>
</join-columns>
<inverse-join-columns>
<join-column name="id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-many field="spApiAfnRecords"
target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonSpApiOrdersAfn" fetch="LAZY">
<join-table name="app-name-here.rmtk_amazon_sp_api_orders_afn">
<join-columns>
<join-column name="amazon_order_id" referenced-column-name="orders_id2"/>
</join-columns>
<inverse-join-columns>
<join-column name="id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-many field="vidrRecords" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonSpApiVidr"
fetch="LAZY">
<join-table name="app-name-here.rmtk_amazon_sp_api_vidr">
<join-columns>
<join-column name="order_id" referenced-column-name="orders_id2"/>
</join-columns>
<inverse-join-columns>
<join-column name="vidr_id" referenced-column-name="vidr_id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
<many-to-many field="scVatTaxReports"
target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonSpApiScVatTaxReports" fetch="LAZY">
<join-table name="app-name-here.rmtk_amazon_sp_api_sc_vat_tax_reports">
<join-columns>
<join-column name="order_id" referenced-column-name="orders_id2"/>
</join-columns>
<inverse-join-columns>
<join-column name="sc_id" referenced-column-name="sc_id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrdersNontangibles"
table="app-name-here.rmtk_orders_nontangibles">
<indexes>
<index name="settlement_id" columns="settlement_id"/>
<index name="orders_id" columns="orders_id"/>
</indexes>
<unique-constraints>
<unique-constraint name="idx_key_id" columns="orders_id,nontangibles_key,nontangibles_subkey"/>
</unique-constraints>
<id name="onId" type="integer" column="on_id">
<generator strategy="IDENTITY"/>
</id>
<field name="nontangiblesKey" type="string" column="nontangibles_key" length="64" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="nontangiblesSubkey" type="string" column="nontangibles_subkey" length="64" nullable="true">
<options>
<option name="fixed"/>
</options>
</field>
<field name="nontangiblesPrice" type="decimal" column="nontangibles_price" precision="15" scale="4"
nullable="false"/>
<field name="nontangiblesTaxRate" type="decimal" column="nontangibles_tax_rate" precision="7" scale="4"
nullable="true"/>
<field name="nontangiblesTaxClass" type="integer" column="nontangibles_tax_class" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<field name="nontangiblesQuantity" type="decimal" column="nontangibles_quantity" precision="15" scale="4"
nullable="false">
<options>
<option name="default">1.0000</option>
</options>
</field>
<field name="issuedcreditnote" type="boolean" column="issuedCreditNote" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="isfromamazonsettlement" type="boolean" column="isFromAmazonSettlement" nullable="false">
<options>
<option name="default">0</option>
</options>
</field>
<field name="ebayReferenceId" type="integer" column="ebay_reference_id" nullable="true">
<options>
<option name="unsigned"/>
</options>
</field>
<many-to-one field="orders" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrders" fetch="LAZY">
<join-columns>
<join-column name="orders_id" referenced-column-name="orders_id"/>
</join-columns>
</many-to-one>
<many-to-one field="settlement" target-entity="ISV-Here\App-Name-Here\Doctrine\Entities\RmtkAmazonSettlements"
fetch="LAZY">
<join-columns>
<join-column name="settlement_id" referenced-column-name="settlement_id"/>
</join-columns>
</many-to-one>
</entity>
</doctrine-mapping>
The end goal is to clone an instance of ISV-Here\App-Name-Here\Doctrine\Entities\RmtkOrders along with its associations. I have implemented __clone() as follows:
class Orders
{
.....
public function __clone()
{
if ($this->ordersId) {
unset($this->ordersId);
$nonTangibleItems = new ArrayCollection();
foreach ($this->nonTangibleItems as $nonTangibleItem) {
$nonTangibleItemClone = clone $nonTangibleItem;
$nonTangibleItemClone->setOrder($this);
$nonTangibleItems->add($nonTangibleItemClone);
}
$this->nonTangibleItems = $nonTangibleItems;
}
}
}
}
My controller is as follows:
/**
* #var RmtkOrders $rmtkOrder
*/
$rmtkOrder = $this->entityManager->find(DOCTRINE_ENTITIES_NAMESPACE . 'RmtkOrders', 123456);
$rmtkOrder->setOrdersId2('das' . time());
$rmtkOrder->setInvoice(null);
$rmtkOrder->setTangibleItems(new ArrayCollection());
$rmtkOrder->setVidrRecords(new ArrayCollection());
$rmtkOrder->setAddresses(new ArrayCollection());
$rmtkOrder->setScVatTaxReports(new ArrayCollection());
$rmtkOrder->setSpApiAfnRecords(new ArrayCollection());
$copy = clone $rmtkOrder;
$this->getEntityManager()->persist($copy);
try {
$this->getEntityManager()->flush($copy);
} catch (Exception $ex) {
Cli::doOutputLine($ex->getMessage());
}
The MariaDB general log shows the following INSERT statements:
2506366 Query INSERT INTO app-name-here.rmtk_orders (orders_id2, username, created_ts, last_update, purchased_ts, remote_addr, comments, channel, hidden, version, user_agent, backend, referral_code, has_settlements_attributed, total_verified, total_verification_ts, non_vies_tax_id, vat_number, vat_number_applied_from_sc_vat_tax_report, vat_number_applied_from_vidr, vat_number_vies_validity, vat_number_vies_validity_verification_ts, exposed_via_api, acknowledged, notify_failed_amazon_invoice_uploads, dispatch_countries_iso_code_2_applied_from_sc_vat_tax_report, dispatch_countries_iso_code_2_applied_from_vidr, magento_entity_id, onbuy_internal_reference, invoice_uploaded_sp_api, kaufland_uploaded, pii_purged, billing_year, billing_month, splitter, dont_invoice, kaufland_id_order_unit, dispatch_countries_iso_code_2, currencies_iso_code, language_code, users_id, slots_id, incoterms_id, supplier_users_id, payment_code, origins_id, domains_id, statuses_id, subpayment_code) VALUES ('das1674928808', 'email-address-here#example.com', '2023-01-28 19:16:48', '2023-01-25 03:22:06', '2023-01-24 00:54:39', NULL, NULL, 'AFN', 0, NULL, NULL, NULL, NULL, 0, 1, '2023-01-28 19:16:50', NULL, '', 1, 0, NULL, NULL, 1, 0, 0, 1, 0, NULL, NULL, 0, NULL, 0, NULL, NULL, 1, 0, NULL, 'FR', 'EUR', 'fr_FR', 260636, 744311, NULL, 55999, 'amazon', 5, 2, 73, NULL)
2506366 Query INSERT INTO app-name-here.rmtk_orders_nontangibles (nontangibles_key, nontangibles_subkey, nontangibles_price, nontangibles_tax_rate, nontangibles_tax_class, nontangibles_quantity, issuedCreditNote, isFromAmazonSettlement, ebay_reference_id, orders_id, settlement_id) VALUES ('shipping', NULL, '0', '20', NULL, '1', 0, 0, NULL, 1893942, NULL)
2506366 Query INSERT INTO app-name-here.rmtk_orders_nontangibles (nontangibles_key, nontangibles_subkey, nontangibles_price, nontangibles_tax_rate, nontangibles_tax_class, nontangibles_quantity, issuedCreditNote, isFromAmazonSettlement, ebay_reference_id, orders_id, settlement_id) VALUES ('shipping_discount', NULL, '0', '20', NULL, '1', 0, 0, NULL, 1893942, NULL)
2506366 Query INSERT INTO app-name-here.rmtk_orders_nontangibles (nontangibles_key, nontangibles_subkey, nontangibles_price, nontangibles_tax_rate, nontangibles_tax_class, nontangibles_quantity, issuedCreditNote, isFromAmazonSettlement, ebay_reference_id, orders_id, settlement_id) VALUES ('promotion_discount', NULL, '0', '20', NULL, '1', 0, 0, NULL, 1893942, NULL)
2506366 Query INSERT INTO app-name-here.rmtk_orders_nontangibles (orders_id, on_id) VALUES (1893942, 1091050)
The very last INSERT statement leads to An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1091053' for key 'PRIMARY'. All the rest of the INSERT statements are exactly as desired.
The very last INSERT statement should not be there at all. Could you spot what the problem is and why this last INSERT statement is executed?

Did you try after clone to detach from the entity manager your new instance ?
$this->getEntityManager()->detach($copy);

I'm not sure to understand your problem, because it sounds like code works (and fails) exactly as expected. As you are cloning RmtkOrders, this is a new entity that doctrine have to persist.
When an object is cloned, a new one is setup with the same properties. So, it fails because the initial entity already has an id and the cloned one duplicate this id. This id violates the unique integrity constraints of primary key when Doctrine try to store it.
In my opinion, if you want to create a new entity and store it, you should implement the magic method __clone() to unset RmtkOrders::id
public function __clone()
{
$this->id = null;
}
Now doctrine will autogenerate a new id on persist.
Optionally, if needed, you perhaps have to clone the subentity in the same way.
public function __clone()
{
$this->id = null;
//the below code is necessary because __construct is NOT called by __clone
$this->setInvoice(null);
$this->setTangibleItems(new ArrayCollection());
$this->setVidrRecords(new ArrayCollection());
$this->setAddresses(new ArrayCollection());
$this->setScVatTaxReports(new ArrayCollection());
$this->setSpApiAfnRecords(new ArrayCollection());
}
and your controller becomes:
/**
* #var RmtkOrders $rmtkOrder
*/
$rmtkOrder = $this->entityManager->find(DOCTRINE_ENTITIES_NAMESPACE . 'RmtkOrders', 123456);
$copy = clone $rmtkOrder;
$copy->setOrdersId2('das' . time()); //I don't understand this line, it could be move to __clone method
$this->getEntityManager()->persist($copy);
try {
$this->getEntityManager()->flush($copy);
} catch (Exception $ex) {
Cli::doOutputLine($ex->getMessage());
}
In any case, I strongly advice you to never update $rmtkOrder, but only manipulate the cloned $clone. And I suggest you to use Model pattern if the magic __clone method is already used for another use case.

Related

BCP insert skip one DB column

I am using a BCP with a file format XML to import from a csv into a SQL database.
It works until I add a new column called DATERIF, that I should skip, but I cannot.
With the following templates, instead of skipping the column, the import is also filling that one, leaving the last one (MODELLO) empty,
I tried to add after the 6th column a row like this one, but in that case an error is raised at runtime.
<COLUMN SOURCE="0" NAME="DATERIF" xsi:type="SQLDATETIME" />
here the complete template file
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="9" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="10" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="11" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="20"
COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="HOSTNAME" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="2" NAME="IP_MACCH" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="3" NAME="LOGIN" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="4" NAME="T_TYPE" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="5" NAME="DATA_RIL" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="6" NAME="ORA_RIL" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="0" NAME="DATERIF" xsi:type="SQLDATETIME"/>
<COLUMN SOURCE="7" NAME="CUSTOMER" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="8" NAME="NUMORDINE" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="9" NAME="OPERATORE" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="10" NAME="SERIALNUM" xsi:type="SQLVARYCHAR" LENGTH="20"/>
<COLUMN SOURCE="11" NAME="MODELLO" xsi:type="SQLVARYCHAR" LENGTH="20"/>
</ROW>
</BCPFORMAT>
How can I skip this field an import in the following ones?
Thank you
Andrea
I am assuming that you are using MS SQL Server.
The scenario where a DB table has one or few additional column(s) is resolved by using a view. That view definition needs to exclude not needed columns. After that you can BULK INSERT into a view instead of the DB table.
It is documented in BOL: Using BULK INSERT with a view

SQL BCP Unknown Error while attempting to read format file on Ubuntu

I'm trying to automate some importing jobs to my SQL Server database and have the following XML format file:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharFixed" LENGTH="11" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="2" xsi:type="CharFixed" LENGTH="30" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="3" xsi:type="CharFixed" LENGTH="2" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="4" xsi:type="CharFixed" LENGTH="2" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="5" xsi:type="CharFixed" LENGTH="2" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="6" xsi:type="CharFixed" LENGTH="1" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="7" xsi:type="CharFixed" LENGTH="1" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="8" xsi:type="CharFixed" LENGTH="2" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
<FIELD ID="9" xsi:type="CharTerm" TERMINATOR="\n"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="cuit" xsi:type="SQLNUMERIC" PRECISION="11" />
<COLUMN SOURCE="2" NAME="denominacion" xsi:type="SQLVARYCHAR" LENGTH="30" />
<COLUMN SOURCE="3" NAME="imp_ganancias" xsi:type="SQLVARYCHAR" LENGTH="2" />
<COLUMN SOURCE="4" NAME="imp_iva" xsi:type="SQLVARYCHAR" LENGTH="2" />
<COLUMN SOURCE="5" NAME="monotributo" xsi:type="SQLVARYCHAR" LENGTH="2" />
<COLUMN SOURCE="6" NAME="integra_sociedad" xsi:type="SQLVARYCHAR" LENGTH="1" />
<COLUMN SOURCE="7" NAME="empleador" xsi:type="SQLVARYCHAR" LENGTH="1" />
<COLUMN SOURCE="8" NAME="actividad_monotributo" xsi:type="SQLVARYCHAR" LENGTH="2" />
</ROW>
</BCPFORMAT>
And it works fine on my local machine running windows 10 if I run the bcp command
bcp myDB.dbo.myTable IN File.txt -f File.xml -U x -P x -S myIp
But the problem is that I need to leave this commands running on a remote machine running on Ubuntu and when I do I get the following error
SQLState = S1000, NativeError = 0
Error = [Microsoft][ODBC Driver 17 for SQL Server]Format File : Unknown error occurred while attempting to read.
And I have no Idea why this is happening, I tried changing permissions on the file and running as root but nothing changes.

T-SQL convert xml field to multi column table

I am trying to convert data from a xml field into a table. I have found multiple solutions on this website, but none of them seem to give me exactly what I need.
The xml looks like this:
<table>
<id>{100}</id>
<rows>
<row>
<columns>
<column name="cur" value="EUR" type="System.String" />
<column name="item" value="Item a" type="System.String" />
<column name="price" value="2.5" type="System.Decimal" />
<column name="qty" value="20" type="System.Int32" />
<column name="Key" value="1" type="System.Int32" />
</columns>
</row>
<row>
<columns>
<column name="cur" value="EUR" type="System.String" />
<column name="item" value="Item b" type="System.String" />
<column name="price" value="30" type="System.Decimal" />
<column name="qty" value="30" type="System.Int32" />
<column name="Key" value="2" type="System.Int32" />
</columns>
</row>
</rows>
<key>Key</key>
</table>
I would like the result to look like this:
id key cur item price qty
100 1 EUR Item a 2.5 20
100 2 EUR Item b 30 30
I hope someone can help me.
Try it like this:
DECLARE #x XML=
'<table>
<id>{100}</id>
<rows>
<row>
<columns>
<column name="cur" value="EUR" type="System.String" />
<column name="item" value="Item a" type="System.String" />
<column name="price" value="2.5" type="System.Decimal" />
<column name="qty" value="20" type="System.Int32" />
<column name="Key" value="1" type="System.Int32" />
</columns>
</row>
<row>
<columns>
<column name="cur" value="EUR" type="System.String" />
<column name="item" value="Item b" type="System.String" />
<column name="price" value="30" type="System.Decimal" />
<column name="qty" value="30" type="System.Int32" />
<column name="Key" value="2" type="System.Int32" />
</columns>
</row>
</rows>
<key>Key</key>
</table>';
SELECT #x.value('(/table/id)[1]','varchar(max)') AS id --are the curly brackets there on purpose?
,Rw.value('(columns/column[#name="Key"]/#value)[1]','int') AS [key]
,Rw.value('(columns/column[#name="cur"]/#value)[1]','varchar(max)') AS cur
,Rw.value('(columns/column[#name="item"]/#value)[1]','varchar(max)') AS item
,Rw.value('(columns/column[#name="price"]/#value)[1]','decimal(10,4)') AS price
,Rw.value('(columns/column[#name="qty"]/#value)[1]','int') AS qty
FROM #x.nodes('/table/rows/row') AS A(Rw)

BULK INSERT tab-delimited file - With commas in Description

I am trying to import a CSV file With the BULK INSERT Function. I am doing it through SQL because it can be an automated process. The problem I picked up is that the CSV file I get from the client has commas in the Item Description i.e Rosetta 10,5x25x4 - When I try to import it that comma in the description causes a problem: Here is the Script I am running:
BULK INSERT ORDERS_DATA
FROM 'C:\back_orders_2013.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
TABLOCK
)
Is there a way to ignore that like in excel where you treat consecutive delimiters as one?
Here is the solution:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="9" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="10" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="11" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="12" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="13" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="14" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="15" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="16" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="17" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="18" xsi:type="CharTerm" TERMINATOR=',' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="19" xsi:type="CharTerm" TERMINATOR='\n' MAX_LENGTH="100" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="RKID" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="2" NAME="ORNO" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="3" NAME="PONO" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="4" NAME="ITEM_CODE" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="5" NAME="ITEM_DESCRIPTION" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="6" NAME="ORDER_QTY" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="7" NAME="DELIVER_QTY" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="8" NAME="B_QTY" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="9" NAME="RTS_DATE" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="10" NAME="PRICE" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="11" NAME="PLEV" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="12" NAME="DISCOUNT1" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="13" NAME="DISCOUNT2" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="14" NAME="DISCOUNT3" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="15" NAME="TOTAL" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="16" NAME="CURRENCY" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="17" NAME="ORDER_DATE" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="18" NAME="BKYN" xsi:type="SQLVARYCHAR" />
<COLUMN SOURCE="19" NAME="PENTA_REF" xsi:type="SQLVARYCHAR" />
</ROW>
</BCPFORMAT>
This works 100% and the error I received:
String or binary data would be truncated. The statement has been
terminated
Was because of the length of one of my data fields.

SQL Bulk copy (unicode)

i have a problem with bulk load into my database. Server throws error "String or binary data would be truncated", but my data seems to be ok.
Im using UTF-16LE data file with XML format file.
Thanks for your answers
Here's my format file:
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="NCharTerm" TERMINATOR=";\0" />
<FIELD ID="2" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="3" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="4" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="5" xsi:type="NCharTerm" TERMINATOR=";\0" />
<FIELD ID="6" xsi:type="NCharTerm" TERMINATOR=";\0" />
<FIELD ID="7" xsi:type="NCharTerm" TERMINATOR=";\0" />
<FIELD ID="8" xsi:type="NCharTerm" TERMINATOR=";\0" />
<FIELD ID="9" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="10" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="11" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="12" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="13" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="14" xsi:type="NCharTerm" TERMINATOR=";\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="15" xsi:type="NCharTerm" TERMINATOR="\n\0" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="RefundId" xsi:type="SQLINT"/>
<COLUMN SOURCE="2" NAME="Date" xsi:type="SQLNCHAR"/>
<COLUMN SOURCE="3" NAME="VariableSymbol" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="RefundType" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="TollAmount" xsi:type="SQLNUMERIC" PRECISION="28" SCALE="12"/>
<COLUMN SOURCE="6" NAME="DepositAmount" xsi:type="SQLNUMERIC" PRECISION="28" SCALE="12"/>
<COLUMN SOURCE="7" NAME="OperativeAmount" xsi:type="SQLNUMERIC" PRECISION="28" SCALE="12"/>
<COLUMN SOURCE="8" NAME="OIAmount" xsi:type="SQLNUMERIC" PRECISION="28" SCALE="12"/>
<COLUMN SOURCE="9" NAME="Currency" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="10" NAME="Prefix" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="11" NAME="BankAccountNumber" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="12" NAME="BankCode" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="13" NAME="BankIBANCode" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="14" NAME="BankSwiftCode" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="15" NAME="BeneficiaryName" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
Here's my data file:
301;2008/05/05;444441;CN;50;1550;70;900;CZK;;8888888888;0800;;;
302;2008/05/06;444442;UP;50;1550;70;900;CZK;;8888888888;1234;;;
303;2008/05/07;444443;OP;50;1550;70;900;CZK;;8888888888;;;;
304;2008/05/08;444444;CN;60;1550;70;900;CZK;;;0400;;;
305;2008/05/09;444445;UP;70;1550;70;900;CZK;;1234567891;0800;;;
306;2008/05/10;444446;OP;80;1550;70;900;CZK;;8888888888;0800;;;
307;2008/05/11;444447;CN;90;1550;70;900;CZK;;8888888888;0800;CZ7308000000008888888888;;
308;2008/05/12;444448;UP;100;1550;70;900;CZK;;8888888888;0800;;12345678901;
309;2008/05/13;444449;OP;110;1550;70;900;CZK;;;;12234567890qqqq;COBADEFF;**123456789012345678901234567890qqqq**
310;2008/05/14;444450;CN;120;1550;70;900;CZK;;;;;COBADEFF;Herr Norbert Ramscheid
312;2008/05/16;444452;OP;140;1550;70;900;CZK;;;;RO49AAAA1B31007593840000;RNCBROBU;Mr. Papalescu
313;2008/05/17;444453;CN;150;1550;70;900;CZK;;678907890;;;RNCBROBU;Mojmir Fagaras
314;2008/05/18;444454;UP;160;1550;70;900;CZK;;;;;RNCBROBU;Mr. Without Bank Account
315;2008/05/19;444455;OP;170;1550;70;900;CZK;;;;RO49AAAA1B31007593840000;;NoSWIFT Bill
316;2008/05/20;444456;CN;180;2000;70;900;CZK;;;;RO49AAAA1B31007593840000;RNCBROBU;
317;2008/05/21;444457;UP;190;1550;70;900;CZK;;;;DE89370400440532013000;COBADEFF;
I assume there could be a problem with a destination table where the data should be loaded into.
Example
E.g. when you are loading data in string of 10 characters into the column which is e.g. varchar(6) data type, the data could not be loaded into this column as it supports only 6 characters and you would get the error as you are getting now - the data would be truncated.