Create file tnsnames.ora from Cloud Control

Hello everyone!

Today we wanted to share with you a script that we have used several times to generate the file tnsnames. ora connection by a query to Cloud Control.

To do this, we use the views mgmt_target_properties and Mgmt $ target. From the first view we consult the values MachineName, PORT and SID to extract the data that we need. The data of the query we export to file and with a small program shell script we generate our new tnsnames.ora.

The query we use for the first part is:

SET PAGESIZE 999
SET LINESIZE 200
SET HEADING OFF
SET TRIMSPOOL ON
SET FEEDBACK OFF

COLUMN host FORMAT A50
COLUMN port FORMAT A10
COLUMN sid FORMAT A30

SPOOL Db_all.txt

SELECT DISTINCT
target.host_name || ‘|’ ||
sid.property_value || ‘|’ ||
port.property_value
FROM sysman.mgmt_target_properties machine
JOIN sysman.mgmt_target_properties sid
ON sid.target_guid = machine.target_guid
JOIN sysman.mgmt_target_properties port
ON port.target_guid = machine.target_guid
JOIN sysman.mgmt_target_properties domain
ON domain.target_guid = machine.target_guid
JOIN sysman.mgmt$target target
ON target.target_guid = machine.target_guid
WHERE machine.property_name = ‘MachineName’
AND port.property_name = ‘Port’
AND sid.property_name = ‘SID’
AND sid.property_value NOT LIKE ‘%ASM%’
AND machine.target_guid IN (
SELECT target_guid
FROM sysman.mgmt_current_availability
WHERE sysman.em_severity.get_avail_string(current_status) = ‘UP’
)
ORDER BY 1;

SPOOL OFF

In the query you search only those instances that are with status “UP”, you can remove the condition to find all. We also have the possibility to search for a specific machine, so we can consult adding:

AND machine. PROPERTY_VALUE = ‘ Maquina1 ‘

One sees generated the file, we look for the values and format the output in tnsnames format.ora:

#!/bin/sh

INPUT_FILE=”Db_all.txt”
OUTPUT_FILE=”tnsnames.ora”

if [ ! -f “$INPUT_FILE” ]; then
echo “Error: input file ‘$INPUT_FILE’ does not exist.” >&2
exit 1
fi

rm -f “$OUTPUT_FILE”

while IFS=’|’ read -r HOST_NAME ORACLE_SID PORT; do
# Ignore blank or incomplete lines.
[ -z “$HOST_NAME” ] && continue
[ -z “$ORACLE_SID” ] && continue
[ -z “$PORT” ] && continue

cat >> “$OUTPUT_FILE” <<EOF
${ORACLE_SID} =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = ${HOST_NAME})
(PORT = ${PORT})
)
)
(CONNECT_DATA =
(SID = ${ORACLE_SID})
)
)

EOF

done < “$INPUT_FILE”

echo “File ‘$OUTPUT_FILE’ created successfully.

We hope you will be as useful as we are.

Greetings.

DBA team.

2 thoughts on “Create file tnsnames.ora from Cloud Control

  1. Tom Leaves

    great query and shell commands.

    But why have spaces been inserted in the statement and single quotes ?

    here is the updated version

    1. sql statement for the first part is :

    set pages 999 lines 200 heading off trimspool off feedback off

    col host for A50
    col port for A10
    col sid for A10

    spool Db_all.txt

    SELECT DISTINCT mgmt$target.host_name || ‘|’ || Sid.PROPERTY_VALUE || ‘|’ || Port.PROPERTY_VALUE
    FROM sysman.mgmt_target_properties machine,
    sysman.mgmt_target_properties port,
    sysman.mgmt_target_properties sid,
    sysman.mgmt_target_properties domain,
    sysman.mgmt$target
    WHERE machine.target_guid = sid.target_guid
    AND sid.target_guid = port.target_guid
    AND port.target_guid = domain.target_guid
    AND Machine.PROPERTY_NAME = ‘MachineName’
    AND port.PROPERTY_NAME = ‘Port’
    AND sid.PROPERTY_NAME = ‘SID’
    AND sid.PROPERTY_VALUE NOT LIKE ‘%ASM%’
    AND Machine.TARGET_GUID IN
    (SELECT TARGET_GUID
    FROM Sysman.mgmt_current_availability
    WHERE sysman.EM_SEVERITY.get_avail_string (current_status) =
    ‘UP’)
    — WHERE current_status in (0,1) )
    AND Machine.TARGET_GUID = mgmt$target.TARGET_GUID
    ORDER BY 1;

    spool off

    2. shell script commands
    rm tnsnames.ora

    cat Db_all.txt | grep -v “^$” | while read each_line
    do
    HOST_NAME=$( echo $each_line | cut -d “|” -f1 )
    ORACLE_SID=$( echo $each_line | cut -d “|” -f2 )
    PORT=$( echo $each_line | cut -d”|” -f3 )

    echo “${ORACLE_SID} =” >> tnsnames.ora
    echo ” (DESCRIPTION =” >> tnsnames.ora
    echo ” (ADDRESS_LIST =” >> tnsnames.ora
    echo ” (ADDRESS =” >> tnsnames.ora
    echo ” (PROTOCOL = TCP)” >> tnsnames.ora
    echo ” (HOST = ${HOST_NAME})” >> tnsnames.ora
    echo ” (PORT = ${PORT})” >> tnsnames.ora
    echo ” )” >> tnsnames.ora
    echo ” )” >> tnsnames.ora
    echo ” (CONNECT_DATA =” >> tnsnames.ora
    echo ” (SERVICE_NAME = ${ORACLE_SID})” >> tnsnames.ora
    echo ” )” >> tnsnames.ora
    echo ” ) ” >> tnsnames.ora

    done

  2. arodriguez

    Hello Tom,

    Thank you very much for your comment and for taking the time to review the SQL query and shell script.

    You were right to point out the unusual spaces. I have checked the original Spanish version of the article, and the code there does not contain spaces inside identifiers such as mgmt$target, filenames such as Db_all.txt, or the concatenation operator ||.

    It appears that these spaces were introduced by the automatic translation or formatting of the English version of the post. For example, the English version may display expressions such as mgmt $ target, Db_all. txt, or | |, although they are written correctly in the original article.

    Regarding the single quotes, those around the pipe character are intentional and required:

    host_name || ‘|’ || sid.property_value || ‘|’ || port.property_value

    The pipe character is a string literal used as a delimiter between the three values, so it must remain inside single quotes. Spaces around the || concatenation operator are optional and do not affect the SQL statement.

    Thank you also for sharing your updated version. I will review the English formatting so that the code is displayed correctly.

    Thanks again for reporting the issue and contributing to the article.

    Best regards,

Leave a Reply

Your email address will not be published. Required fields are marked *