diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 0f3ca46d98..65aac70b9e 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -385,11 +385,24 @@ class FormatStylePlaceholderCursor:
 
     def __init__(self, connection):
         self.cursor = connection.cursor()
-        # Necessary to retrieve decimal values without rounding error.
-        self.cursor.numbersAsStrings = True
+        self.cursor.outputtypehandler = self._output_type_handler
         # The default for cx_Oracle < 5.3 is 50.
         self.cursor.arraysize = 100
 
+    @staticmethod
+    def _output_type_handler(cursor, name, defaultType, length, precision, scale):
+        """
+        Called for each db column fetched from cursors. Return numbers as
+        strings so that decimal values don't have rounding error.
+        """
+        if defaultType == Database.NUMBER:
+            return cursor.var(
+                Database.STRING,
+                size=255,
+                arraysize=cursor.arraysize,
+                outconverter=str,
+            )
+
     def _format_params(self, params):
         try:
             return {k: OracleParam(v, self, True) for k, v in params.items()}