MetricSign
Start free
Low severityschema

SQL Server Error:
4104

What does this error mean?

SQL Server gooit error 4104 wanneer de query engine een identifier met meerdere delen — zoals schema.table.column of server.database.schema.object — niet kan oplossen naar een bestaand object. Dit betekent dat één van de onderdelen niet bestaat, verkeerd gespeld is, of buiten scope valt op het moment dat SQL Server de query logisch verwerkt. In een data-pipeline-context leidt dit altijd tot een harde fout: ADF-activiteiten stoppen met status Failed, dbt-modellen compileren niet, en SSRS-rapporten geven een lege dataset of een rode foutmelding. De engineer ziet de exacte identifier in de foutmelding — dat is de startplaats van het onderzoek.

Common causes

  • 1Een query gebruikt een vier-part name (server.database.schema.object) maar de linked server bestaat niet of is offline — SQL Server kan het eerste deel van de identifier niet resolven.
  • 2Een column alias gedefinieerd in SELECT wordt gebruikt in een WHERE- of HAVING-clause. SQL Server verwerkt WHERE vóór SELECT in de logische verwerkingsvolgorde, waardoor het alias op dat punt nog niet bestaat.
  • 3Een JOIN definieert een tabel-alias (bijv. FROM orders o) maar elders in de query wordt de originele tabelnaam gebruikt in table.column-notatie — de twee identifiers conflicteren.
  • 4Een dbt-model gebruikt ref() of source() waarbij de gegenereerde identifier afwijkt van het schema dat de onderliggende SQL verwacht — bijvoorbeeld wanneer een custom schema-macro een ander prefix toevoegt dan de query aanneemt.
  • 5Een view of stored procedure verwijst naar een kolom die na een schema-migratie hernoemd of verwijderd is — de definitie in sys.sql_modules is verouderd en de binding faalt bij uitvoering.
  • 6In Azure Data Factory wordt een dynamische expressie of parameter gebruikt die een tabelnaam opbouwt met een ontbrekend schemaprefix, waardoor de gegenereerde SQL een incomplete identifier bevat.
  • 7Een query gebruikt een subquery-alias in de buitenste FROM-clause zonder die alias correct te kwalificeren, of verwijst naar een CTE-naam die buiten de WITH-scope valt.

How to fix it

  1. 1Stap 1 — Isoleer het exacte probleem-identifier uit de foutmelding en verifieer elk onderdeel: SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'jouw_schema' AND TABLE_NAME = 'jouw_tabel' AND COLUMN_NAME = 'jouw_kolom'; — als de rij ontbreekt, bestaat het object niet in deze database.
  2. 2Stap 2 — Controleer of het een alias-in-WHERE probleem is: herschrijf de query met een CTE. Vervang SELECT col * 2 AS doubled FROM t WHERE doubled > 10 door: WITH cte AS (SELECT col * 2 AS doubled FROM t) SELECT * FROM cte WHERE doubled > 10;
  3. 3Stap 3 — Verifieer linked server-beschikbaarheid als de identifier vier delen heeft: SELECT name, is_linked FROM sys.servers; — voer daarna EXEC sp_testlinkedserver 'linked_server_name'; uit om te checken of de verbinding actief is.
  4. 4Stap 4 — Controleer JOIN-aliassen: zoek in de query alle FROM- en JOIN-clausules en zet elke tabelreferentie in table.column-notatie om naar alias.column-notatie. Gebruik SELECT * FROM sys.dm_exec_describe_first_result_set(N'jouw_query', NULL, 0); om kolommen te inspecteren zonder de query volledig uit te voeren.
  5. 5Stap 5 — Valideer views en stored procedures op verouderde kolom-referenties: SELECT OBJECT_NAME(object_id), definition FROM sys.sql_modules WHERE definition LIKE '%verouderd_kolom_naam%'; — herbouw de view met CREATE OR ALTER VIEW als de kolom hernoemd is.
  6. 6Stap 6 — Controleer voor dbt-projecten de gegenereerde SQL in target/compiled/ en vergelijk het schema-prefix met wat INFORMATION_SCHEMA.SCHEMATA teruggeeft: SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA; — pas de dbt_project.yml schema-configuratie aan als er een mismatch is.
  7. 7Stap 7 — Controleer in Azure Data Factory de parameterexpressie die de tabelnaam opbouwt via de Debug-tab in de Copy- of Lookup-activiteit. Zorg dat de expressie altijd het volledige schema.tabel patroon produceert en voeg een Validation-activiteit toe die de identifier checkt vóór de hoofdactiviteit loopt.

Example log output

ErrorCode=SqlOperationFailed, Message=A network-related or instance-specific error... Activity ID: ...
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The multi-part identifier "dbo.fact_orders.order_id" could not be bound.
SQL State: S0001, Error Code: 4104

Frequently asked questions

Hoe fix ik 'multi-part identifier could not be bound' snel in productie?

Kopieer het exacte identifier uit de foutmelding en verifieer elk onderdeel met INFORMATION_SCHEMA.COLUMNS. Het meest voorkomende geval is een typefoute alias of een schemaprefix dat ontbreekt — voeg het ontbrekende deel toe of herschrijf de alias naar een CTE.

Kan ik error 4104 omzeilen met een retry in ADF?

Nee. Dit is een codefout, geen transiënte fout. Retries geven exact hetzelfde resultaat. De pipeline-activiteit moet stopgezet worden, de SQL gerepareerd, en de run opnieuw getriggerd.

Waarom geeft mijn dbt-model ineens 4104 na een schema-rename?

dbt genereert de identifier op basis van de configuratie in dbt_project.yml en de schema-macro. Als het schema hernoemd is maar de macro of het target-schema niet bijgewerkt is, verwijst de gegenereerde SQL naar het oude schema. Check target/compiled/ voor de letterlijke SQL en vergelijk het schema met sys.schemas.

Kan error 4104 optreden bij een view die gisteren nog werkte?

Ja — als een onderliggende tabel of kolom hernoemd of verwijderd is na het aanmaken van de view, faalt de binding pas bij uitvoering. SQL Server valideert view-definities niet automatisch na schema-wijzigingen. Gebruik SELECT OBJECT_NAME(referencing_id) FROM sys.sql_expression_dependencies WHERE referenced_entity_name = 'verwijderd_object'; om afhankelijke views te vinden.

Source · learn.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-events-and-errors

Other schema errors