Skip to content

Oracle

Signals reads conversion and customer data straight from an Oracle database on a schedule and sends the columns you nominate to your ad platforms.

Reading it directly means there is no file job to maintain and nothing to go stale between runs. Signals reads only; nothing is written back.

You can point it at a table, or at a query. The query path is what you want when the shape Signals needs does not match anything you already have.

A read against a busy table can fail after it has already returned rows. Oracle serves a read-consistent view of the table from undo, and if the undo it still needs has been overwritten by other sessions before the scan finishes, the statement stops with ORA-01555, snapshot too old. A scheduled read is where this appears first, because it tends to be the longest-running query against that table and the one nobody is watching. Undo retention and the size of the undo tablespace govern it, so the fix belongs with whoever sizes those rather than in another attempt at the same read.

In Studio, open Sources, find the Database category, and click the Oracle tile.

FieldWhat it isWhere to find it
Authentication NameYour own label for this set of credentials.You choose it. Name it for the database it belongs to.
UsernameThe database user Signals connects as.Created in the database by your administrator.
PasswordThe password for that user.Set when the user was created.

Oracle addresses databases by service name rather than by a simple database name. Enter the value your connection strings already use.

Two privileges are needed and they are granted separately. Which one is missing decides how the connection fails:

GRANT CREATE SESSION TO datahash;
GRANT SELECT ON analytics.conversions TO datahash;

An account holding only the second cannot log in. Oracle refuses it with ORA-01045, which names the missing CREATE SESSION privilege and denies the logon, so a privilege gap presents itself as an account problem. GRANT CONNECT TO datahash does the same work, the CONNECT role having carried nothing but CREATE SESSION since Oracle 10g Release 2. Resist SELECT ANY TABLE when a single table grant looks too small to be right: it reads every table in every schema, and everything anyone creates after it was granted.

A user created while connected to the container root of a multitenant database is a common user, and its name has to begin with the prefix in COMMON_USER_PREFIX, which is C## by default. Oracle rejects the CREATE USER with ORA-65096 rather than accepting the name you asked for. Needing that prefix is the signal you are in the wrong container: the account Signals connects as belongs in the pluggable database that holds the data, created while connected to that PDB. Multitenant arrived in Oracle 12c and the non-container architecture is desupported on current releases, so this applies to a recent database whether or not anyone on the team uses the word.

Select the Integration Type, which is the kind of data your records hold. Offline Events is the common choice. Give the instance a name, then choose the table path or the query path. On either path you enter the Host Name, Port and Database Name, and then either the Table Name or a SQL query.

The integration type decides the columns Signals expects and which destinations the connection can feed, so it is worth settling before anyone models the data. It also decides which file format you get on the next screen.

1521 is where the listener answers unless it has been moved. The value that belongs in Database Name is a service name, and a service name is not a SID: they are separate keys, resolved separately, and a listener carries no obligation to answer to both for the same database. Host, port, user and password can all be correct while the attempt ends at the listener, before any password is compared, because the name given matches neither a service it has registered nor a SID it serves.

lsnrctl services on the database host lists what the listener will accept. Take the value from there, or from a connection string already in use, rather than from the instance name or the host name: those coincide with the service name often enough to look like a rule and not often enough to depend on. In a multitenant database each pluggable database registers a service of its own, named after the PDB by default, so this field also decides which PDB the session lands in.

Enter the connection details including the table name, then complete the setup. The name is typed rather than picked from a list, so it has to match the database exactly.

Enter the connection details without the table name, then write the query. Preview the results before finishing, and read the column names in the output rather than just the row count: a query that runs but returns the wrong names will fail silently once the connection is live.

One instance reads one table or query for one integration type. To read another, add another instance from the Manage existing instance table. To change an existing one, open it from there, click the edit option in the menu to the top right, update the fields and click Finish.

Download the file format from the setup screen and shape the table to it. The column names are what Signals matches on, so a column that has been renamed or cased differently is not recognized and the row it belongs to is dropped rather than reported.

On the query path the same rule applies to the column aliases your query returns. Aliasing to the expected names is the usual way to reconcile data you cannot or should not restructure.

Personal identifiers are normalized and hashed before they are sent to a destination.

  • Use a dedicated read-only user scoped to the data Datahash reads, rather than an application account.
  • Prefer the query path with explicit column aliases over pointing at a raw table. It lets your team change the underlying model without breaking the connection.
  • Find out what a standby costs your organization before designing this read around one. A Data Guard physical standby sits mounted while it applies redo, and a mounted database answers no query at all. Keeping it open read only while redo apply continues is Active Data Guard, licensed separately from Enterprise Edition, so the standby your DBA already runs for failover is very probably not one you can select from. Where the license is absent, the remaining option is to halt redo apply for the duration of each read, and the standby falls further behind the primary for as long as it is halted.
  • Give the user CREATE SESSION so it can log in and SELECT on the specific table or view so it can read, and nothing beyond those two. An account granted only the second is rejected at logon.
  • Clean the data in the view or query: lowercase email, phone in E.164, no stray whitespace. Hashing a badly formatted value produces a hash that will never match.
  • Rotate the password periodically and update the connection afterwards.

The connection times out rather than reporting bad credentials. That points at reachability rather than authentication. Confirm the host is exposed, the port is open, and any firewall or allow list permits the connection.

Credentials are rejected. Check the user can read the data from a client of its own first. Most failures here are permissions rather than typos.

The table name is rejected. It is typed rather than selected, so it has to match exactly. Oracle uppercases unquoted identifiers, so a table created with a lower case name may need quoting.

The attempt fails at the listener, naming a service rather than the credentials. ORA-12514 reports that the listener does not know the service in the connect descriptor, which is what a wrong or unregistered service name produces. Its counterpart ORA-12505 is what the listener returns when a value reaches it as a SID it does not serve, so either error tells you the name was the problem rather than the account. Both arrive after TCP has connected and before Oracle compares a password, so rotating the credentials changes nothing, and getting either one back is evidence that the host and the port are right. Compare the value in Database Name against lsnrctl services on the database host, and read that list for what is absent as well as what is there: a service whose instance is down never registers, and a pluggable database left MOUNTED rather than opened READ WRITE does not register its service either, so the same error also covers a database that is not open.

The query previews correctly but nothing is delivered. The column names it returns do not match the expected schema. Alias them to the names in the downloaded file format.

It was working and stopped. The password may have been changed or the user disabled. A dedicated service user avoids this.