Commits

Anonymous committed 088b1c6

Fixed #11487: pass long strings to Oracle as CLOB rather than NCLOB to prevent an encoding bug that occurs in some installations. Backport of [11285] from trunk.

Comments (0)

Files changed (2)

django/db/backends/oracle/base.py

     """
     Wrapper object for formatting parameters for Oracle. If the string
     representation of the value is large enough (greater than 4000 characters)
-    the input size needs to be set as NCLOB. Alternatively, if the parameter
+    the input size needs to be set as CLOB. Alternatively, if the parameter
     has an `input_size` attribute, then the value of the `input_size` attribute
     will be used instead. Otherwise, no input size will be set for the
     parameter when executing the query.
             # If parameter has `input_size` attribute, use that.
             self.input_size = param.input_size
         elif isinstance(param, basestring) and len(param) > 4000:
-            # Mark any string param greater than 4000 characters as an NCLOB.
-            self.input_size = Database.NCLOB
+            # Mark any string param greater than 4000 characters as a CLOB.
+            self.input_size = Database.CLOB
         else:
             self.input_size = None
 

tests/regressiontests/backends/tests.py

             return True
         else:
             return True
+            
+class LongString(unittest.TestCase):
 
+    def test_long_string(self):
+        # If the backend is Oracle, test that we can save a text longer
+        # than 4000 chars and read it properly
+        if settings.DATABASE_ENGINE == 'oracle':
+            c = connection.cursor()
+            c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
+            long_str = ''.join([unicode(x) for x in xrange(4000)])
+            c.execute('INSERT INTO ltext VALUES (%s)',[long_str])
+            c.execute('SELECT text FROM ltext')
+            row = c.fetchone()
+            c.execute('DROP TABLE ltext')
+            self.assertEquals(long_str, row[0].read())
 
 if __name__ == '__main__':
     unittest.main()